aiohttp的异步爬虫使用方法

2024-01-21 03:48

本文主要是介绍aiohttp的异步爬虫使用方法,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

aiohttp是python3的一个异步模块,分为服务器端和客户端。廖雪峰的python3教程中,讲的是服务器端的使用方法。均益这里主要讲的是客户端的方法,用来写爬虫。使用异步协程的方式写爬虫,能提高程序的运行效率。

1、安装

Python
pip install <span class="wp_keywordlink_affiliate"><a href="https://www.168seo.cn/tag/aiohttp" title="View all posts in aiohttp" target="_blank">aiohttp</a></span>
1
2
pip install aiohttp

2、单一请求方法

Python
import aiohttp import asyncio async def fetch(session, url): async with session.get(url) as response: return await response.text() async def main(url): async with aiohttp.ClientSession() as session: html = await fetch(session, url) print(html) url = 'http://junyiseo.com' loop = asyncio.get_event_loop() loop.run_until_complete(main(url))
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import aiohttp
import asyncio
async def fetch ( session , url ) :
async with session . get ( url ) as response :
return await response . text ( )
async def main ( url ) :
async with aiohttp . ClientSession ( ) as session :
html = await fetch ( session , url )
print ( html )
url = 'http://junyiseo.com'
loop = asyncio . get_event_loop ( )
loop . run_until_complete ( main ( url ) )

3、多url请求方法

Python
import aiohttp import asyncio async def fetch(session, url): async with session.get(url) as response: return await response.text() async def main(url): async with aiohttp.ClientSession() as session: html = await fetch(session, url) print(html) loop = asyncio.get_event_loop() # 生成多个请求方法 url = "http://junyiseo.com" tasks = [main(url), main(url)] loop.run_until_complete(asyncio.wait(tasks)) loop.close()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import aiohttp
import asyncio
async def fetch ( session , url ) :
async with session . get ( url ) as response :
return await response . text ( )
async def main ( url ) :
async with aiohttp . ClientSession ( ) as session :
html = await fetch ( session , url )
print ( html )
loop = asyncio . get_event_loop ( )
# 生成多个请求方法
url = "http://junyiseo.com"
tasks = [ main ( url ) , main ( url ) ]
loop . run_until_complete ( asyncio . wait ( tasks ) )
loop . close ( )

4、其他的请求方式

上面的代码中,我们创建了一个 ClientSession 对象命名为session,然后通过session的get方法得到一个 ClientResponse 对象,命名为resp,get方法中传入了一个必须的参数url,就是要获得源码的http url。至此便通过协程完成了一个异步IO的get请求。
aiohttp也支持其他的请求方式

Python
session.post('http://httpbin.org/post', data=b'data') session.put('http://httpbin.org/put', data=b'data') session.delete('http://httpbin.org/delete') session.head('http://httpbin.org/get') session.options('http://httpbin.org/get') session.patch('http://httpbin.org/patch', data=b'data')
1
2
3
4
5
6
7
8
session . post ( 'http://httpbin.org/post' , data = b 'data' )
session . put ( 'http://httpbin.org/put' , data = b 'data' )
session . delete ( 'http://httpbin.org/delete' )
session . head ( 'http://httpbin.org/get' )
session . options ( 'http://httpbin.org/get' )
session . patch ( 'http://httpbin.org/patch' , data = b 'data' )

5、请求方法中携带参数

GET方法带参数

Python
params = {'key1': 'value1', 'key2': 'value2'} async with session.get('http://httpbin.org/get', params=params) as resp: expect = 'http://httpbin.org/get?key2=value2&key1=value1' assert str(resp.url) == expect
1
2
3
4
5
6
params = { 'key1' : 'value1' , 'key2' : 'value2' }
async with session . get ( 'http://httpbin.org/get' ,
params = params ) as resp :
expect = 'http://httpbin.org/get?key2=value2&key1=value1'
assert str ( resp . url ) == expect

POST方法带参数

Python
payload = {'key1': 'value1', 'key2': 'value2'} async with session.post('http://httpbin.org/post', data=payload) as resp: print(await resp.text())
1
2
3
4
5
payload = { 'key1' : 'value1' , 'key2' : 'value2' }
async with session . post ( 'http://httpbin.org/post' ,
data = payload ) as resp :
print ( await resp . text ( ) )

6、获取响应内容

resp.status 是http状态码,
resp.text() 是网页内容

Python
async with session.get('https://api.github.com/events') as resp: print(resp.status) print(await resp.text())
1
2
3
4
async with session . get ( 'https://api.github.com/events' ) as resp :
print ( resp . status )
print ( await resp . text ( ) )

gzip和deflate转换编码已经为你自动解码。

7、JSON请求处理

Python
async with aiohttp.ClientSession() as session: async with session.post(url, json={'test': 'object'})
1
2
3
async with aiohttp . ClientSession ( ) as session :
async with session . post ( url , json = { 'test' : 'object' } )

返回json数据的处理

Python
async with session.get('https://api.github.com/events') as resp: print(await resp.json())
1
2
3
async with session . get ( 'https://api.github.com/events' ) as resp :
print ( await resp . json ( ) )

8、以字节流的方式读取文件,可以用来下载

Python
async with session.get('https://api.github.com/events') as resp: await resp.content.read(10) #读取前10个字节
1
2
3
async with session . get ( 'https://api.github.com/events' ) as resp :
await resp . content . read ( 10 ) #读取前10个字节

下载保存文件

Python
with open(filename, 'wb') as fd: while True: chunk = await resp.content.read(chunk_size) if not chunk: break fd.write(chunk)
1
2
3
4
5
6
7
with open ( filename , 'wb' ) as fd :
while True :
chunk = await resp . content . read ( chunk_size )
if not chunk :
break
fd . write ( chunk )

9、上传文件

Python
url = 'http://httpbin.org/post' files = {'file': open('report.xls', 'rb')} await session.post(url, data=files)
1
2
3
4
5
url = 'http://httpbin.org/post'
files = { 'file' : open ( 'report.xls' , 'rb' ) }
await session . post ( url , data = files )

可以设置好文件名和content-type:

Python
url = 'http://httpbin.org/post' data = FormData() data.add_field('file', open('report.xls', 'rb'), filename='report.xls', content_type='application/vnd.ms-excel') await session.post(url, data=data)
1
2
3
4
5
6
7
8
9
url = 'http://httpbin.org/post'
data = FormData ( )
data . add_field ( 'file' ,
open ( 'report.xls' , 'rb' ) ,
filename = 'report.xls' ,
content_type = 'application/vnd.ms-excel' )
await session . post ( url , data = data )

10、超时处理

默认的IO操作都有5分钟的响应时间 我们可以通过 timeout 进行重写,如果 timeout=None 或者 timeout=0 将不进行超时检查,也就是不限时长。

Python
async with session.get('https://github.com', timeout=60) as r: ...
1
2
3
async with session . get ( 'https://github.com' , timeout = 60 ) as r :
. . .

11、自定义请求头

Python
url = 'http://example.com/image' payload = b'GIF89a\x01\x00\x01\x00\x00\xff\x00,\x00\x00' b'\x00\x00\x01\x00\x01\x00\x00\x02\x00;' headers = {'content-type': 'image/gif'} await session.post(url, data=payload, headers=headers)
1
2
3
4
5
6
7
8
9
url = 'http://example.com/image'
payload = b 'GIF89a\x01\x00\x01\x00\x00\xff\x00,\x00\x00'
b '\x00\x00\x01\x00\x01\x00\x00\x02\x00;'
headers = { 'content-type' : 'image/gif' }
await session . post ( url ,
data = payload ,
headers = headers )

设置session的请求头

Python
headers={"Authorization": "Basic bG9naW46cGFzcw=="} async with aiohttp.ClientSession(headers=headers) as session: async with session.get("http://httpbin.org/headers") as r: json_body = await r.json() assert json_body['headers']['Authorization'] == \ 'Basic bG9naW46cGFzcw=='
1
2
3
4
5
6
7
headers = { "Authorization" : "Basic bG9naW46cGFzcw==" }
async with aiohttp . ClientSession ( headers = headers ) as session :
async with session . get ( "http://httpbin.org/headers" ) as r :
json_body = await r . json ( )
assert json_body [ 'headers' ] [ 'Authorization' ] == \
'Basic bG9naW46cGFzcw=='

12、自定义cookie

Python
url = 'http://httpbin.org/cookies' cookies = {'cookies_are': 'working'} async with ClientSession(cookies=cookies) as session: async with session.get(url) as resp: assert await resp.json() == { "cookies": {"cookies_are": "working"}}
1
2
3
4
5
6
7
url = 'http://httpbin.org/cookies'
cookies = { 'cookies_are' : 'working' }
async with ClientSession ( cookies = cookies ) as session :
async with session . get ( url ) as resp :
assert await resp . json ( ) == {
"cookies" : { "cookies_are" : "working" } }

在多个请求中共享cookie

Python
async with aiohttp.ClientSession() as session: await session.get( 'http://httpbin.org/cookies/set?my_cookie=my_value') filtered = session.cookie_jar.filter_cookies( 'http://httpbin.org') assert filtered['my_cookie'].value == 'my_value' async with session.get('http://httpbin.org/cookies') as r: json_body = await r.json() assert json_body['cookies']['my_cookie'] == 'my_value'
1
2
3
4
5
6
7
8
9
10
async with aiohttp . ClientSession ( ) as session :
await session . get (
'http://httpbin.org/cookies/set?my_cookie=my_value' )
filtered = session . cookie_jar . filter_cookies (
'http://httpbin.org' )
assert filtered [ 'my_cookie' ] . value == 'my_value'
async with session . get ( 'http://httpbin.org/cookies' ) as r :
json_body = await r . json ( )
assert json_body [ 'cookies' ] [ 'my_cookie' ] == 'my_value'

13、限制同时请求数量

limit默认是100,limit=0的时候是无限制

Python
conn = aiohttp.TCPConnector(limit=30)
1
2
conn = aiohttp . TCPConnector ( limit = 30 )

14、SSL加密请求

有的请求需要验证加密证书,可以设置ssl=False,取消验证

Python
r = await session.get('https://example.com', ssl=False)
1
2
r = await session . get ( 'https://example.com' , ssl = False )

加入证书

Python
sslcontext = ssl.create_default_context( cafile='/path/to/ca-bundle.crt') r = await session.get('https://example.com', ssl=sslcontext)
1
2
3
4
sslcontext = ssl . create_default_context (
cafile = '/path/to/ca-bundle.crt' )
r = await session . get ( 'https://example.com' , ssl = sslcontext )

15、代理请求

Python
async with aiohttp.ClientSession() as session: async with session.get("http://<span class="wp_keywordlink"><a href="http://www.168seo.cn/python" title="python">python</a></span>.org", proxy="http://proxy.com") as resp: print(resp.status)
1
2
3
4
5
async with aiohttp . ClientSession ( ) as session :
async with session . get ( "http://python.org" ,
proxy = "http://proxy.com" ) as resp :
print ( resp . status )

代理认证

Python
async with aiohttp.ClientSession() as session: proxy_auth = aiohttp.BasicAuth('user', 'pass') async with session.get("http://<span class="wp_keywordlink"><a href="http://www.168seo.cn/python" title="python">python</a></span>.org", proxy="http://proxy.com", proxy_auth=proxy_auth) as resp: print(resp.status)
1
2
3
4
5
6
7
async with aiohttp . ClientSession ( ) as session :
proxy_auth = aiohttp . BasicAuth ( 'user' , 'pass' )
async with session . get ( "http://python.org" ,
proxy = "http://proxy.com" ,
proxy_auth = proxy_auth ) as resp :
print ( resp . status )

或者通过URL认证

Python
session.get("http://python.org", proxy="http://user:pass@some.proxy.com")
1
2
3
session . get ( "http://python.org" ,
proxy = "http://user:pass@some.proxy.com" )

16、优雅的关闭程序

没有ssl的情况,加入这个语句关闭await asyncio.sleep(0)

Python
async def read_website(): async with aiohttp.ClientSession() as session: async with session.get('http://example.org/') as resp: await resp.read() loop = asyncio.get_event_loop() loop.run_until_complete(read_website()) # Zero-sleep to allow underlying connections to close loop.run_until_complete(asyncio.sleep(0)) loop.close()
1
2
3
4
5
6
7
8
9
10
11
async def read_website ( ) :
async with aiohttp . ClientSession ( ) as session :
async with session . get ( 'http://example.org/' ) as resp :
await resp . read ( )
loop = asyncio . get_event_loop ( )
loop . run_until_complete ( read_website ( ) )
# Zero-sleep to allow underlying connections to close
loop . run_until_complete ( asyncio . sleep ( 0 ) )
loop . close ( )

如果是ssl请求,在关闭前需要等待一会

Python
loop.run_until_complete(asyncio.sleep(0.250)) loop.close()
1
2
3
loop . run_until_complete ( asyncio . sleep ( 0.250 ) )
loop . close ( )

*** 转自均益博客




  • zeropython 微信公众号 5868037 QQ号 5868037@qq.com QQ邮箱

这篇关于aiohttp的异步爬虫使用方法的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/628284

相关文章

PHP轻松处理千万行数据的方法详解

《PHP轻松处理千万行数据的方法详解》说到处理大数据集,PHP通常不是第一个想到的语言,但如果你曾经需要处理数百万行数据而不让服务器崩溃或内存耗尽,你就会知道PHP用对了工具有多强大,下面小编就... 目录问题的本质php 中的数据流处理:为什么必不可少生成器:内存高效的迭代方式流量控制:避免系统过载一次性

Python使用FastAPI实现大文件分片上传与断点续传功能

《Python使用FastAPI实现大文件分片上传与断点续传功能》大文件直传常遇到超时、网络抖动失败、失败后只能重传的问题,分片上传+断点续传可以把大文件拆成若干小块逐个上传,并在中断后从已完成分片继... 目录一、接口设计二、服务端实现(FastAPI)2.1 运行环境2.2 目录结构建议2.3 serv

Spring Security简介、使用与最佳实践

《SpringSecurity简介、使用与最佳实践》SpringSecurity是一个能够为基于Spring的企业应用系统提供声明式的安全访问控制解决方案的安全框架,本文给大家介绍SpringSec... 目录一、如何理解 Spring Security?—— 核心思想二、如何在 Java 项目中使用?——

springboot中使用okhttp3的小结

《springboot中使用okhttp3的小结》OkHttp3是一个JavaHTTP客户端,可以处理各种请求类型,比如GET、POST、PUT等,并且支持高效的HTTP连接池、请求和响应缓存、以及异... 在 Spring Boot 项目中使用 OkHttp3 进行 HTTP 请求是一个高效且流行的方式。

python获取指定名字的程序的文件路径的两种方法

《python获取指定名字的程序的文件路径的两种方法》本文主要介绍了python获取指定名字的程序的文件路径的两种方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要... 最近在做项目,需要用到给定一个程序名字就可以自动获取到这个程序在Windows系统下的绝对路径,以下

Java使用Javassist动态生成HelloWorld类

《Java使用Javassist动态生成HelloWorld类》Javassist是一个非常强大的字节码操作和定义库,它允许开发者在运行时创建新的类或者修改现有的类,本文将简单介绍如何使用Javass... 目录1. Javassist简介2. 环境准备3. 动态生成HelloWorld类3.1 创建CtC

JavaScript中的高级调试方法全攻略指南

《JavaScript中的高级调试方法全攻略指南》什么是高级JavaScript调试技巧,它比console.log有何优势,如何使用断点调试定位问题,通过本文,我们将深入解答这些问题,带您从理论到实... 目录观点与案例结合观点1观点2观点3观点4观点5高级调试技巧详解实战案例断点调试:定位变量错误性能分

使用Python批量将.ncm格式的音频文件转换为.mp3格式的实战详解

《使用Python批量将.ncm格式的音频文件转换为.mp3格式的实战详解》本文详细介绍了如何使用Python通过ncmdump工具批量将.ncm音频转换为.mp3的步骤,包括安装、配置ffmpeg环... 目录1. 前言2. 安装 ncmdump3. 实现 .ncm 转 .mp34. 执行过程5. 执行结

Python中 try / except / else / finally 异常处理方法详解

《Python中try/except/else/finally异常处理方法详解》:本文主要介绍Python中try/except/else/finally异常处理方法的相关资料,涵... 目录1. 基本结构2. 各部分的作用tryexceptelsefinally3. 执行流程总结4. 常见用法(1)多个e

Java使用jar命令配置服务器端口的完整指南

《Java使用jar命令配置服务器端口的完整指南》本文将详细介绍如何使用java-jar命令启动应用,并重点讲解如何配置服务器端口,同时提供一个实用的Web工具来简化这一过程,希望对大家有所帮助... 目录1. Java Jar文件简介1.1 什么是Jar文件1.2 创建可执行Jar文件2. 使用java