urllib2 urlopen读取超时/阻止
作者:互联网
最近,我正在研究一个小型爬虫,用于在URL上下载图像.
我在urllib2中将openurl()与f.open()/ f.write()结合使用:
这是代码片段:
# the list for the images' urls
imglist = re.findall(regImg,pageHtml)
# iterate to download images
for index in xrange(1,len(imglist)+1):
img = urllib2.urlopen(imglist[index-1])
f = open(r'E:\OK\%s.jpg' % str(index), 'wb')
print('To Read...')
# potential timeout, may block for a long time
# so I wonder whether there is any mechanism to enable retry when time exceeds a certain threshold
f.write(img.read())
f.close()
print('Image %d is ready !' % index)
在上面的代码中,img.read()可能会长时间阻塞,我希望在此问题下进行一些重试/重新打开图像URL操作.
我还关注上面代码的高效视角,如果要下载的图像数量太大,那么使用线程池下载它们似乎更好.
有什么建议么?提前致谢.
ps.我发现img对象上的read()方法可能导致阻塞,因此仅将超时参数添加到urlopen()似乎没用.但是我发现文件对象没有read()的超时版本.有什么建议吗?非常感谢 .
解决方法:
urllib2.urlopen
有一个超时参数,用于所有阻塞操作(连接建立等).
此摘录摘自我的一个项目.我使用线程池一次下载多个文件.它使用urllib.urlretrieve,但逻辑相同. url_and_path_list是(URL,路径)元组的列表,num_concurrent是要产生的线程数,如果文件已存在于文件系统中,则skip_existing跳过文件的下载.
def download_urls(url_and_path_list, num_concurrent, skip_existing):
# prepare the queue
queue = Queue.Queue()
for url_and_path in url_and_path_list:
queue.put(url_and_path)
# start the requested number of download threads to download the files
threads = []
for _ in range(num_concurrent):
t = DownloadThread(queue, skip_existing)
t.daemon = True
t.start()
queue.join()
class DownloadThread(threading.Thread):
def __init__(self, queue, skip_existing):
super(DownloadThread, self).__init__()
self.queue = queue
self.skip_existing = skip_existing
def run(self):
while True:
#grabs url from queue
url, path = self.queue.get()
if self.skip_existing and exists(path):
# skip if requested
self.queue.task_done()
continue
try:
urllib.urlretrieve(url, path)
except IOError:
print "Error downloading url '%s'." % url
#signals to queue job is done
self.queue.task_done()
标签:multithreading,urllib2,python,web-crawler 来源: https://codeday.me/bug/20191031/1976577.html