网站验收时项目建设总结报告,机加工接单什么平台好,做物流运输网站电话,公司网站建设代码都写完了如果有多个URL等待我们爬取#xff0c;我们通常是一次只能爬取一个#xff0c;爬取效率低#xff0c;异步爬虫可以提高爬取效率#xff0c;可以一次多多个URL同时同时发起请求
异步爬虫方式#xff1a; 一、多线程、多进程#xff08;不建议#xff09;#xff1a;可以…如果有多个URL等待我们爬取我们通常是一次只能爬取一个爬取效率低异步爬虫可以提高爬取效率可以一次多多个URL同时同时发起请求
异步爬虫方式 一、多线程、多进程不建议可以为爬取阻塞多个URL等待爬取单独开启线程或进程多个爬取URL异步执行不能开启无限多个 二、线程池、进程池可以降低系统对进程或者线程创建和消除的频率从而降低系统的开销池中进程或线程的数量是有上限的 一、单线程串行爬取
用时间延时模拟爬取每个网址的耗时时间 单线程爬取一次只能爬取一个以下面为例一次爬取一个爬取4个需要8秒
import time# 模拟爬取每个网址耗时
def get_page(url):time.sleep(2)# 开始时间
start_time time.time()
# URL
url_list [url1, url2, url3, url4]
for url in url_list:get_page(url)
# 结束时间
end_time time.time()
# 输出总耗时
print(end_time-start_time)二、多线程并行爬取
一次可以对多个URL同时进行爬取以下面为例开启4个进程则可以对4个URL同时发起请求总时间为2秒
import time
from multiprocessing.dummy import Pool# 模拟爬取每个网址耗时
def get_page(url):time.sleep(2)url_list [url1, url2, url3, url4]
# 开始时间
start_time time.time()
# 实例化线程对象,4表示开启了4个进程
pool Pool(4)
# 讲列表中url_list每一个列表元素传递给get_page进行处理
pool.map(get_page, url_list)
# 结束时间
end_time time.time()
print(end_time-start_time)三、单线程异步协程
event_loop事件循环相当于一个无限循环可以把一些函数注册到这个循环上当满足某些条件的时候函数就会被循环执行 coroutine:协程对象我们可以将协程对象注册到事件循环中它会被事件循环调用。我们可以使用async关键字来定义一个方法这个方法在调用时不会立即被执行而是返回一个协程对象。 task:任务它是对协程对象的进一步封装包含了任务的各个状态。 future:代表将来执行或还没有执行的任务实际上和 task没有本质区别。async定义一个协程。 await用来挂起阻塞方法的执行。
import asyncioasync def request(url):print(模拟请求)# 调用async修饰的函数之后返回一个协程对象
c request(url)
# 创建一个事件循环对象
loop asyncio.new_event_loop()
# 将协程对象注册到loop中.然后启动loop
loop.run_until_complete(c)
print(c)
# coroutine object request at 0x000001F5BDDA8040task的使用
import asyncioasync def request(url):print(模拟请求)# 调用async修饰的函数之后返回一个协程对象
c request(https://www.baidu.com)
# 创建一个事件循环对象
loop asyncio.new_event_loop()
# 基于loop创建一个task对象
task loop.create_task(c)
# 注册循环之前的输出
print(task)
loop.run_until_complete(task)
# 注册循环之后的输出
print(task)输出如下
Task pending nameTask-1 cororequest() running at E:\Code\pythonProject\main.py:4
模拟请求
Task finished nameTask-1 cororequest() done, defined at E:\Code\pythonProject\main.py:4 resultNonefuture的使用
import asyncioasync def request(url):print(模拟请求)# 调用async修饰的函数之后返回一个协程对象
c request(https://www.baidu.com)
# 创建一个事件循环对象
loop asyncio.new_event_loop()
# 基于loop创建一个task对象
task asyncio.ensure_future(c, looploop)
print(task)
loop.run_until_complete(task)
print(task)Task pending nameTask-1 cororequest() running at E:\Code\pythonProject\main.py:3
模拟请求
Task finished nameTask-1 cororequest() done, defined at E:\Code\pythonProject\main.py:3 resultNone1、绑定回调
import asyncioasync def request(url):print(模拟请求)return urldef callback_func(task):# result返回的是任务对象中封装的携程对象对应函数的返回值即上面返回的urlprint(task.result())# async修饰的函数,调用之后返回的一个协程对象
c request(url)loop asyncio.new_event_loop()
task asyncio.ensure_future(c, looploop)
# 将回调函数绑定到任务对象中
task.add_done_callback(callback_func) # task
loop.run_until_complete(task)模拟请求
url2、多任务协成
在异步协成中如果出现了同步模块相关的代码那么就无法实现异步如下面的time.sleep(2)下面代码没起到异步作用爬取三个网站需要6秒左右
import asyncio
import timeasync def request(url):print(模拟请求)# 在异步协成中如果出现了同步模块相关的代码那么就无法实现异步time.sleep(2)return urlstart time.time()
urls [aaa, bbb, ccc]
# 任务列表存放多个任务对象
stasks []# 将任务对象列表注册到事件循环当中
loop asyncio.new_event_loop()
for url in urls:c request(url)task asyncio.ensure_future(c, looploop)stasks.append(task)# 需要将任务列表封装到wait中
loop.run_until_complete(asyncio.wait(stasks))
print(time.time() - start)模拟请求
模拟请求
模拟请求
6.002672433853149这里就需要使用asyncio.sleep当在asyncio中遇到阻塞操作必须进行手动挂起使用await挂起如下方法起到了异步左右爬取三个URL只需要2秒左右
import asyncio
import timeasync def request(url):print(模拟请求)# 当在asyncio中遇到阻塞操作必须进行手动挂起await asyncio.sleep(2)return urlstart time.time()
urls [aaa, bbb, ccc]
# 任务列表存放多个任务对象
stasks []# 将任务对象列表注册到事件循环当中
loop asyncio.new_event_loop()
for url in urls:c request(url)task asyncio.ensure_future(c, looploop)stasks.append(task)# 需要将任务列表封装到wait中
loop.run_until_complete(asyncio.wait(stasks))
print(time.time() - start)模拟请求
模拟请求
模拟请求
2.0162434577941895requests.get请求是基于同步的那么就无法实现异步耗时较长
async def request(url):# requests.get请求是基于同步的那么就无法实现异步response requests.get(urlurl)必须使用基于异步的网络请求模块进行请求发送 aiohttp:基于异步网络请求的模块 pip install aiohttp
import aiohttpasync def request(url):async with aiohttp.ClientSession() as session: # 返回session对象# 将get改为post为post请求# 参数headers,params/data,proxyhttp://ip:portasync with await session.get(url) as response: # 返回response对象# text()返回字符串形式的响应数据# read()返回二进制形式的响应数据# json()返回的是json对象# 注意在获取响应数据操作之前一定要使用await进行手动挂起page_text await response.text()