异步爬虫的方式
高性能异步爬虫:在爬虫中使用异步实现高性能的数据爬取操作
异步爬虫的方式:
1.多线程、多进程(不建议):
好处:可以为相关阻塞的操作单独开启线程或者进程,阻塞操作就可以进行异步执行。
弊端:无法无限制的开启多线程或者多进程。
2.线程池、进程池:
好处:可以降低系统对进程或者线程创建或者销毁的一个频率,从而很好的降低系统的开销。
弊端:池中线程或者进程的数量是有上限。
3.**单线程+异步协程(推荐)**
enent_loop:事件循环,相当于一个无限循环,我们可以把一些函数注册到这个事件循环上,当满足某些条件的时候,函数就会被循环执行。
coroutine:协程对象,我们可以将协程对象注册到事件循环中,它会被事件循环调用。可以使用async 关键字来定义一个方法,这个方法在调用时不会立即被执行,而是返回一个协程对象。
task:任务,它是对协程对象的进一步封装,包含了任务的各个状态。
future:代表将来执行或者还没有执行的任务,实际上和task没有本质区别。
async:定义一个协程
await:用来挂起阻塞方法的执行。
实战1.单线程串行
import time
# 使用单线程串行的方式执行
def get_page(str):
print('正在下载:',str)
time.sleep(2)
print('下载成功:',str)
name_list = ['xiaozi','a','b','c']
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))
运行结束后:
正在下载: xiaozi
下载成功: xiaozi
正在下载: a
下载成功: a
正在下载: b
下载成功: b
正在下载: c
下载成功: c
8 second
实战2.线程池爬取
import time
#导入线程池模块对应的类
from multiprocessing.dummy import Pool
#使用线程池方式执行
start_time = time.time()
def get_page(str):
print("正在下载",str)
time.sleep(2)
print("下载成功:",str)
name_list = ['xiaozi','a','b','c']
#实例化一个线程池对象
pool = Pool(4)
#将列表中每一个列表元素传递给get_page进行处理
pool.map(get_page,name_list) #使用线程池pool类中的map方法,输入get_page函数,name_list:类似于爬取的不同的url
end_time =time.time()
print(end_time-start_time) #单线程下载是8s,但是本次线程池中共有4个线程,因此是8/4
实战3.线程池爬取网页
线程池处理的是阻塞且耗时的操作
待补充
额外知识:
1.打开页面,右击检查
2.选择【Network】--->选择url
3.选择页面的是否为动态加载数据的图片、文字或者视频等,然后在【Response】下的查找中查找该属性,如果显示未查找到,则表示该数据为动态加载的数据
4.则选择【XHR】进行抓取