胶水Python

urlretrieve下载卡死无法超时的问题

2019-02-16  本文已影响0人  爱折腾的大懒猪

在使用Biopython 进行PDB文件下载时, 当文件多了, 经常性会卡死. 这种卡死的问题往往可以通过设置超时timeout值来控制. 当连接时间大于超时时间, 就会发生超时错误, 从而避免卡死的问题.

经查源代码, Biopython使用urllib库的urlretrieve方法进行文件的下载. 经查, 该方法并没有timeout参数可以控制超时. 因此不能简单地避免这个问题.

想运用requestsget方法进行下载, 然而, 又发现下载时报错. 原来, pdb文件下载地址是ftp链接地址. requests库不支持ftp协议.

好吧, 然后尝试了wget 模块, 经尝试wget也能进行ftp的下载. 但是在实际测试中发现, wget同样存在假死的问题.. 打断后发现, 原来wget底层是使用urlretrieve 进行下载的.. 怪不得也不支持timeout参数.


经查阅, 有一个方法可以使得urlretrieve进行超时的使用socket模块 (Python Socket 编程详细介绍).

import socket
# 设置超时30s
socket.settimeout(30)

socket的超时对urllib同样是起效的. 当设置后, 下载超时是报错: timeout: timed out.

一种简单的处理是:

try:
        urllib.urlretrieve(url,filename)
except socket.timeout:
        print 'Network conditions is not good. Re-download....'
        urllib.urlretrieve(url,filename)

高级一点的处理是:

import socket
import urllib
#设置超时时间为30s
socket.setdefaulttimeout(30)
#解决下载不完全问题且避免陷入死循环
try:
    urllib.urlretrieve(url,filename)
except socket.timeout:
    count = 1
    while count <= 5:
        try:
            urllib.urlretrieve(url,filename)                                                
            break
        except socket.timeout:
            err_info = 'Reloading for %d time'%count if count == 1 else 'Reloading for %d times'%count
            print(err_info)
            count += 1
    if count > 5:
        print("download job failed!")
上一篇下一篇

猜你喜欢

热点阅读