1.任务背景
现已提供数据文件,其中两个字段是ftp链接,每一条数据有两个链接,链接对应开放服务器的文件列表,该项任务主要把文件列表中指定的压缩包文件下载下来。
数据如图所示:
在浏览器中打开对应的某个ftp链接,如下图所示,目标是将其中红框中的压缩包下载下来,一个ftp下载一个,一条数据对应下载两个压缩包:
2.数据预处理
由于python爬虫的requests库请求的url都是以http/https打头,所有首先做的操作是将每个ftp链接前缀转换为http/https,代码如下:
def changePre(data): #更换url前缀为https
hurlsGen=[] #存放所有转换完成的Gen FTP链接
hurlsRef=[] #存放所有转换完成的Ref FTP链接
i=0
while i<len(data): #循环遍历所有数据进行转换
data=data.astype(str)
furlGen = data['GenBank FTP'][i].strip()[3:]
furlRef = data['RefSeq FTP'][i].strip()[3:]
hurlGen = 'https' + furlGen+'/'
hurlRef = 'https' + furlRef+'/'
hurlsGen.append(hurlGen)
hurlsRef.append(hurlRef)
i+=1
return hurlsGen,hurlsRef
3.得到每条转换后的url对应的HTML代码
def getHTMLText(url, code="utf-8"): #得到转换后的每条url对应的HTML代码
try:
r = requests.get(url)
r.raise_for_status()
r.encoding = code
return r.text
except:
return ""
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:
file=requests.get(basicUrl+filename) #指定文件的下载链接
if file.status_code==200: #可能有的链接不含指定文件 此时会生成一个空文件,文件名为:序号_RNG
f.write(file.content)
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代码
try:
r = requests.get(url)
r.raise_for_status()
r.encoding = code
return r.text
except:
return ""
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:
file=requests.get(basicUrl+filename) #指定文件的下载链接
if file.status_code==200: #可能有的链接不含指定文件 此时会生成一个空文件,文件名为:序号_RNG
f.write(file.content)
def changePre(data): #更换url前缀为https
hurlsGen=[] #存放所有转换完成的Gen FTP链接
hurlsRef=[] #存放所有转换完成的Ref FTP链接
i=0
while i<len(data): #循环遍历所有数据进行转换
data=data.astype(str)
furlGen = data['GenBank FTP'][i].strip()[3:]
furlRef = data['RefSeq FTP'][i].strip()[3:]
hurlGen = 'https' + furlGen+'/'
hurlRef = 'https' + furlRef+'/'
hurlsGen.append(hurlGen)
hurlsRef.append(hurlRef)
i+=1
return hurlsGen,hurlsRef
def Write(urls,title):
count=1
for url in urls:
if not os.path.exists(title):
os.mkdir(title)
html = getHTMLText(url)
#print(html)
filename = parseHTMLText(html)
filepath = title
writeFile(url, filename, filepath,count)
count+=1
hurlsGen=[]
hurlsReq=[]
def main():
data=pd.read_csv('prokaryotes.csv')
#data=data.head()
hurlsGen,hurlsReq=changePre(data)
#hurlsGen=["https://ftp.ncbi.nlm.nih.gov/genomes/all/GCA/000/504/085/GCA_000504085.1_ASM50408v1"]
Write(hurlsGen,'Gen')
Write(hurlsReq,'Req')
if __name__=='__main__':
main()
8.问题:
数据文件总共有1w多条数据,对应2w多条链接,发现利用上述方式下载文件的速度很慢。不知道是网络原因,还是代码本身有问题...费解...