python多线程下载文件

从文件中读取图片url和名称,将url中的文件下载下来。文件中每一行包含一个url和文件名,用制表符隔开。

1、使用requests请求url并下载文件

def download(img_url, img_name):
    with closing(requests.get(img_url, stream=True)) as r:
        with open(os.path.join(out_dir, img_name), 'wb') as f:
            for data in r.iter_content(1024):
                f.write(data)

 

2、从文件中读取url,考虑文件较大,使用生成器的方式读取。

def get_imgurl_generate():
    with open('./example.txt', 'r') as f:
        for line in f:
            line = line.strip()
            yield imgs

 

3、使用多线程进行下载

lock = threading.Lock()
def loop(imgs):
    while True:
        try:
            with lock:
                img_url, img_name = next(imgs)
        except StopIteration:
            break
        download_pic(img_url, img_name)

img_gen = imgurl_generate()

for i in range(0, thread_num):
    t = threading.Thread(target=loop, args=(img_gen,))
    t.start()

 

完整代码,加入异常处理

 1 # -*- coding: utf-8 -*-
 2 import os
 3 from contextlib import closing
 4 import threading
 5 import requests
 6 import time
 7 
 8 
 9 headers = {
10 'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36'
11 }
12 
13 #输出文件夹
14 out_dir = './output'
15 #线程数
16 thread_num = 20
17 #http请求超时设置
18 timeout = 5
19 
20 if not os.path.exists(out_dir):
21     os.mkdir(out_dir)
22 
23 
24 
25 def download(img_url, img_name):
26     if os.path.isfile(os.path.join(out_dir, img_name)):
27         return
28     with closing(requests.get(img_url, stream=True, headers=headers, timeout=timeout)) as r:
29         rc = r.status_code
30         if 299 < rc or rc < 200:
31             print 'returnCode%s\t%s' % (rc, img_url)
32             return
33         content_length = int(r.headers.get('content-length', '0'))
34         if content_length == 0:
35             print 'size0\t%s' % img_url
36             return
37         try:
38             with open(os.path.join(out_dir, img_name), 'wb') as f:
39                 for data in r.iter_content(1024):
40                     f.write(data)
41         except:
42             print 'savefail\t%s' % img_url
43 
44 def get_imgurl_generate():
45     with open('./final.scp', 'r') as f:
46         index = 0
47         for line in f:
48             index += 1
49             if index % 500 == 0:
50                 print 'execute %s line at %s' % (index, time.time())
51             if not line:
52                 print ur'line %s is empty "\t"' % index
53                 continue
54             line = line.strip()
55             try:
56                 imgs = line.split('\t')
57                 if len(imgs) != 2:
58                     print ur'line %s splite error' % index
59                     continue
60                 if not imgs[0] or not imgs[1]:
61                     print ur'line %s img is empty' % index
62                     continue
63                 yield imgs
64             except:
65                 print ur'line %s can not split by "\t"' % index
66 
67 
68 lock = threading.Lock()
69 def loop(imgs):
70     print 'thread %s is running...' % threading.current_thread().name
71 
72     while True:
73         try:
74             with lock:
75                 img_url, img_name = next(imgs)
76         except StopIteration:
77             break
78         try:
79             download(img_url, img_name)
80         except:
81             print 'exceptfail\t%s' % img_url
82     print 'thread %s is end...' % threading.current_thread().name
83 
84 img_gen = get_imgurl_generate()
85 
86 for i in range(0, thread_num):
87     t = threading.Thread(target=loop, name='LoopThread %s' % i, args=(img_gen,))
88     t.start()
View Code

 

posted @ 2017-05-01 23:34  lwli  阅读(14412)  评论(0编辑  收藏  举报