python分布式爬虫并解决假死问题

python版本:3.5.4
系统:win10 x64

通过网页下载视频

方法一:使用urllib.retrieve函数

放函数只需要两个参数即可下载相应内容到本地,一个是网址,一个是保存位置

import urllib.request
url = 'http://xxx.com/xxx.mp4'
file = 'xxx.mp4'
urllib.request.retrieve(url, file)

但是博主在使用过程中发现,该函数没有timeout方法。使用时,可能由于网络问题导致假死!

方法二:使用urllib.request.urlopen函数

使用方法如下:

import urllib.request
url = 'http://xxx.com/xxx.mp4'
file = 'xxx.mp4'
response = urllib.request.urlopen(url, timeout=5)
data = response.read()
with open(file, 'wb') as video:
    video.write(data)

此函数有timeout设置,可以避免假死。

使程序并行化

伪代码如下:

import urllib.request
import socket
from urllib import error
from queue import Queue
from threading import Thread
import os

class DownloadWorker(Thread):  #定义一个类,继承自thread类,重写其run函数
    def __init__(self, queue):
        Thread.__init__(self)
        self.queue = queue     #标准的多线程实现方法都使用了queue

    def run(self):
        while True:
            link, file = self.queue.get() #从队列中获取一组网址以及对应的保存位置
            try: #使用try except方法进行各种异常处理
                response = urllib.request.urlopen(link, timeout=5)
                data = response.read()
                with open(file, 'wb') as video:
                    video.write(data)
            except error.HTTPError as err: 
                print('HTTPerror, code: %s' % err.code)
            except error.URLError as err:
                print('URLerror, reason: %s' % err.reason)
            except socket.timeout:
                print('Time Out!')
            except:
                print('Unkown Error!')
            self.queue.task_done() #标记队列中的一个元素已经被处理


def main():
    queue = Queue() #定义队列

    for x in range(8): #开启8个线程
        worker = DownloadWorker(queue)
        worker.daemon = True
        worker.start()

    for lineData in txtData: #向队列中放入数据
        link = lineData[0]
        file = lineData[1]
        queue.put((link, file))

    queue.join() #等待队列中的数据被处理完毕


if __name__ == '__main__':
    main()
已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 编程工作室 设计师:CSDN官方博客 返回首页