1.任务背景
现已提供数据文件,其中两个字段是ftp链接,每一条数据有两个链接,链接对应开放服务器的文件列表,该项任务主要把文件列表中指定的压缩包文件下载下来。
数据如图所示:
在浏览器中打开对应的某个ftp链接,如下图所示,目标是将其中红框中的压缩包下载下来,一个ftp下载一个,一条数据对应下载两个压缩包:
2.数据预处理
1)去除GenBank FTP以及RefSeq FTP字段值为空的数据,代码如下:
def delete_Null(data):
print(len(data))
print(data['GenBank FTP'].isnull().value_counts())
data['GenBank FTP']=data['GenBank FTP'].fillna("-1")
row1=data[data['GenBank FTP']=="-1"].index.tolist()
data=data.drop(row1)
print(len(data))
print(data['RefSeq FTP'].isnull().value_counts())
data['RefSeq FTP']=data['RefSeq FTP'].fillna("-1")
row2=data[data['RefSeq FTP']=="-1"].index.tolist()
data=data.drop(row2)
print(len(data))
return data
2)由于python爬虫的requests库请求的url都是以http/https打头,所有首先做的操作是将每个ftp链接前缀转换为http/https,代码如下:
def changePre(data): #更换url前缀为https
hurlsGen=[] #存放所有转换完成的Gen FTP链接
hurlsRef=[] #存放所有转换完成的Ref FTP链接
i=0
while i
3.得到每条转换后的url对应的HTML代码
def getHTMLText(url, code="utf-8"): #得到转换后的每条url对应的HTML代码
while(1): #加入重试机制,若某次超时或未请求到HTML代码;则重复请求,直到拿到HTML代码为止
try:
headers={
'User-Agent':'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36'
}
r = requests.get(url,headers=headers)
r.raise_for_status()
r.encoding = code
print(r.status_code)
if r.status_code==200:
return r.text
except:
print ("fail")
continue
4.分析网页源码
如上图所示,可以发现代码非常简单,所有文件链接都在a标签中。
5.解析HTML代码,提取指定下载文件的文件名。
def parseHTMLText(html): #解析网页源码,提取指定下载文件的文件名
doc=pq(html) #用pyquery提取a标签
a=doc('a')
filename='RNG' #默认文件名为RNG
for item in a.items(): #遍历所有提取的a标签,根据href属性值,找到指定的下载文件的文件名
if 'protein.gpff.gz' in item.attr('href'):
filename=item.attr('href')
print(filename)
return filename
6.提取待下载的文件,并写在本地文件夹中
def writeFile(basicUrl,filename,filepath,count):
filepath1='{0}/{1}'.format(filepath,str(count)+'_'+filename)#本地写入路径
if not os.path.exists(filepath1):
with open(filepath1,'wb') as f:
if filename!='RNG': #存在目标文件
while(1): #加入重试机制,直到拿到目标文件并写入本地成功为止
try:
file=requests.get(basicUrl+filename) #指定文件的下载链接
if file.status_code==200:
f.write(file.content)
print("write sussess\n")
return
except:
continue
else: #文件名为RNG说明不存在目标文件,此时会生成一个空文件,文件名为:序号_RNG
print("write fail\n")
7.全部代码:
#-*- coding:utf-8 -*-
import requests
import os
from pyquery import PyQuery as pq
import pandas as pd
from multiprocessing import Pool
def getHTMLText(url, code="utf-8"): #得到转换后的每条url对应的HTML代码
while(1): #加入重试机制,若某次超时或未请求到HTML代码;则重复请求,直到拿到HTML代码为止
try:
headers={
'User-Agent':'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36'
}
r = requests.get(url,headers=headers)
r.raise_for_status()
r.encoding = code
print(r.status_code)
if r.status_code==200:
return r.text
except:
print ("fail")
continue
def parseHTMLText(html): #解析网页源码,提取指定下载文件的文件名
doc=pq(html) #用pyquery提取a标签
a=doc('a')
filename='RNG' #默认文件名为RNG
for item in a.items(): #遍历所有提取的a标签,根据href属性值,找到指定的下载文件的文件名
if 'protein.gpff.gz' in item.attr('href'):
filename=item.attr('href')
print(filename)
return filename
def writeFile(basicUrl,filename,filepath,count):
filepath1='{0}/{1}'.format(filepath,str(count)+'_'+filename)#本地写入路径
if not os.path.exists(filepath1):
with open(filepath1,'wb') as f:
if filename!='RNG': #存在目标文件
while(1): #加入重试机制,直到拿到目标文件并写入本地成功为止
try:
file=requests.get(basicUrl+filename) #指定文件的下载链接
if file.status_code==200:
f.write(file.content)
print("write sussess\n")
return
except:
continue
else: #文件名为RNG说明不存在目标文件,此时会生成一个空文件,文件名为:序号_RNG
print("write fail\n")
def changePre(data): #更换url前缀为https
hurlsGen=[] #存放所有转换完成的Gen FTP链接
hurlsRef=[] #存放所有转换完成的Ref FTP链接
i=0
while i