给初学者参考:
下面程序使用多线程的map()方法,实现多线程下载同一个URL下的资源,使用第三方包requests来进行HTTP下载。
基础知识:
1.高阶函数:能接收其他函数作为参数的函数,称为高阶函数。
2.map(参数1,参数2[,参数3,...])函数说明
- 参数说明:参数1为函数对象;参数2为可循环对象,参数2的每一个元素依次作为参数1的入参,若参数1需要多个入参,那么就会有后面的参数3到参数n;
- map函数最终会返回一个迭代器,在Python2.7中返回是一个列表。
3.使用公司网络时可能会需要设置代理:
(1)定义代理
proxies = {
"http": "http://user:pass@代理ip:代理端口号/",
"https": "http://user:pass@代理ip:代理端口号/"
}
(2)使用代理
r=requests.get(address,proxies=proxies) # 注意:此处写成proxies=xxx(xxx为定义的代理)才可以。
并行实现程序如下:
# -*- coding:utf8 -*-
"""多线程下载
1.使用公司内网时需要设置代理
2.在使用requests时将代理作为参数输入(此处写成proxies=xxx(xxx为定义的代理)才可以)"""
import time
from multiprocessing import Pool
import requests
# 定义代理
proxies = {
"http": "http://user:pass@192.168.1.158:8080/",
"https": "http://user:pass@192.168.1.158:8080/"
}
# 定义装饰器
def decorator_timer(old_function):
def new_function(*arg,**dict_arg):
t1 =time.time()
result=old_function(*arg,**dict_arg)
t2 =time.time()
print("time:",t2-t1)
return result
return new_function
# 函数处理(下载某一路径下资源)
def visit_once(i,address="https://blog.csdn.net/HXiao0805"): # 此处网址为内网可直接访问,若访问外网需要设置代理
r=requests.get(address,proxies=proxies) # 注意:此处写成proxies=xxx(xxx为定义的代理)才可以
return r.status_code
# 单线程
@decorator_timer
def single_thread(f,counts):
result = map(f,range(counts)) # map高阶函数(参数1为一个函数名;参数2为一个可循环对象,其中每个元素依次作为参数1函数的参数)
return list(result)
# 多线程
@decorator_timer
def multiple_thread(f,counts,process_number=10):
p=Pool(process_number) # 开启10个线程同时跑
return p.map(f,range(counts))
# 睡眠函数(当操作某个函数过于频繁时可使用)
def avoid_10060(fun):
error_time = 0
while True:
time.sleep(1)
try:
return fun()
except:
error_time += 1
if error_time == 100:
print 'your network is little bad'
time.sleep(60)
if error_time == 101:
print 'your network is broken'
break
continue
break
if __name__=="__main__":
TOTAL =3 # 总数越多越能体现出多线程优势
#single_thread(avoid_10060(visit_once),TOTAL)
print(single_thread(visit_once,TOTAL))
print(multiple_thread(visit_once,TOTAL))
喜欢我的文章希望和我一起成长的宝宝们,可以搜索并添加公众号TryTestwonderful ,或者扫描下方二维码添加公众号