目的: 在爬虫中使用异步实现高性能的数据爬去操作。
同步爬取(效率低下):
import requests
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) '
'Chrome/89.0.4389.90 Safari/537.36 Edg/89.0.774.63 '
}
urls = [
'url 1',
'url 2',
'url 3'
]
def get_content(url):
print("正在爬取", url)
# get方法是一个阻塞的方法
response = requests.get(url=url, headers=headers)
if response.status_code == 200:
return response.content
def parse_content(content):
print('响应数据的长度为:', len(content))
for url in urls:
content = get_content(url)
parse_content(content)
异步爬虫的的方式:
- 1.多线程,多进程(不建议):
- 好处:单个线程的阻塞不会影响其他线程的运行。
- 弊端:无法无限制的开启多线程或多进程 - 2.线程池,进程池(适当的使用):
- 好处:我们可以降低系统对进程或者进程创建和销毁的频率,从而很好的降低系统的开销。
- 弊端:池中线程或进程的数量是有上限的。
线程池举例:
# import time
# # 使用单线程串行方式进行
# def get_page(str):
# print('正在下载:',str)
# time.sleep(1)
# print("下载成功:",str)
#
#
# # 模拟4个url
# name_list = ['xiaozi','aa','bb','cc']
#
#
# 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))
# 使用线程池方式执行
import time
# 导入线程池模块对应的类
from multiprocessing.dummy import Pool
start_time = time.time()
def get_page(str):
print('正在下载:',str)
time.sleep(1)
print('下载成功:',str)
# 模拟4个url
name_list = ['xiaozi','aa','bb','cc']
# 实例化一个线程池对象
pool = Pool(4)
# 将列表中每一个列表元素传递给get_page进行处理。
pool.map(get_page,name_list)
end_time = time.time()
print(f"总共用时:{end_time-start_time}")