异步爬虫-异步爬虫(单线程串行、多线程&多进程 、进程池或者线程池)
一、单线程串行方式爬取
- 单线程下使用串行方式请求发送,获取请求相应方式 :
import requests
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.141 Safari/537.36'
}
urls = ['http://down.chinaz.com/download.asp?id=36160&dp=1&fid=23&f=yes', 'http://down.chinaz.com/download.asp?id=38883&dp=1&fid=23&f=yes']
def get_content(url):
print('正在爬取:' , url)
# GET 请求是一个阻塞的方法,线程需要等待执行完毕后,才会执行其他的请求方法
resopnse = requests.get(url=url, headers=headers)
if resopnse.status_code == 200:
return resopnse.content
def parse_content(content):
print('相应数据的长度:' , len(content))
for url in urls:
content = get_content(url)
parse_content(content)
二、异步爬虫方式
2.1、多线程、多进程 (不建议使用)
- 优势 :可以为相关阻塞的操作单独开启线程或进程,阻塞操作就可以异步执行;
- 劣势 :无法无限制的开启多线程或者多进程;
#使用单线程串行方式执行
import time
#模拟爬虫
def get_page(str):
print('正在下载:',str)
time.sleep(3) #模拟发送请求和获取响应数据需要的时间
print('下载成功:',str)
name_list = ['xiaozi','aa','bb','cc'] #模拟url
start_time = time.time()
for i in range(len(name_list)):
get_page(name_list[i])
end_time = time.time()
print('%d second'%(end_time-start_time)) #程序执行完成需要的时间,12秒
2.2、进程池或者线程池(适当地使用)
- 优势:可以降低系统对进程或者线程创建和销毁的频率,从而降低系统的开销
- 劣势:池中进程或者线程的数量有限制
#使用线程池方式执行
import time
from multiprocessing.dummy import Pool #导入线程池模块对应的类
start_time = time.time()
#模拟爬虫
def get_page(str):
print('正在下载:',str)
time.sleep(3) #模拟发送请求和获取响应数据需要的时间
print('下载成功:',str)
name_list = ['xiaozi','aa','bb','cc'] #模拟url
#实例化一个线程池对象
pool = Pool(4) #处理4个请求阻塞
#将列表中每一个元素传递给get_page进行处理
pool.map(get_page,name_list) #第一个参数是函数,第二个参数是列表
end_time = time.time()
print('%d second'%(end_time-start_time)) #程序执行完成需要的时间,3秒
向往的地方很远,喜欢的东西很贵,这就是我努力的目标。