這篇文章將為大家詳細(xì)講解有關(guān)aiohttp怎么在python中使用,文章內(nèi)容質(zhì)量較高,因此小編分享給大家做個參考,希望大家閱讀完這篇文章后對相關(guān)知識有一定的了解。
在寧城等地區(qū),都構(gòu)建了全面的區(qū)域性戰(zhàn)略布局,加強(qiáng)發(fā)展的系統(tǒng)性、市場前瞻性、產(chǎn)品創(chuàng)新能力,以專注、極致的服務(wù)理念,為客戶提供網(wǎng)站建設(shè)、成都網(wǎng)站制作 網(wǎng)站設(shè)計制作按需求定制開發(fā),公司網(wǎng)站建設(shè),企業(yè)網(wǎng)站建設(shè),高端網(wǎng)站設(shè)計,全網(wǎng)整合營銷推廣,成都外貿(mào)網(wǎng)站建設(shè),寧城網(wǎng)站建設(shè)費用合理。1.aiohttp的簡單使用(配合asyncio模塊)
import asyncio,aiohttp async def fetch_async(url): print(url) async with aiohttp.request("GET",url) as r: reponse = await r.text(encoding="utf-8") #或者直接await r.read()不編碼,直接讀取,適合于圖像等無法編碼文件 print(reponse) tasks = [fetch_async('http://www.baidu.com/'), fetch_async('http://www.chouti.com/')] event_loop = asyncio.get_event_loop() results = event_loop.run_until_complete(asyncio.gather(*tasks)) event_loop.close()
2.發(fā)起一個session請求
import asyncio,aiohttp async def fetch_async(url): print(url) async with aiohttp.ClientSession() as session: #協(xié)程嵌套,只需要處理最外層協(xié)程即可fetch_async async with session.get(url) as resp: print(resp.status) print(await resp.text()) #因為這里使用到了await關(guān)鍵字,實現(xiàn)異步,所有他上面的函數(shù)體需要聲明為異步async tasks = [fetch_async('http://www.baidu.com/'), fetch_async('http://www.cnblogs.com/ssyfj/')] event_loop = asyncio.get_event_loop() results = event_loop.run_until_complete(asyncio.gather(*tasks)) event_loop.close()
除了上面的get方法外,會話還支持post,put,delete....等
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')
不要為每次的連接都創(chuàng)建一次session,一般情況下只需要創(chuàng)建一個session,然后使用這個session執(zhí)行所有的請求。
每個session對象,內(nèi)部包含了一個連接池,并且將會保持連接和連接復(fù)用(默認(rèn)開啟)可以加快整體的性能。
3.在url中傳遞參數(shù)(其實與requests模塊使用大致相同)
只需要將參數(shù)字典,傳入params參數(shù)中即可[code]import asyncio,aiohttp
import asyncio,aiohttp async def func1(url,params): async with aiohttp.ClientSession() as session: async with session.get(url,params=params) as r: print(r.url) print(await r.read()) tasks = [func1('https://www.ckook.com/forum.php',{"gid":6}),] event_loop = asyncio.get_event_loop() results = event_loop.run_until_complete(asyncio.gather(*tasks)) event_loop.close()
4.獲取響應(yīng)內(nèi)容(由于獲取響應(yīng)內(nèi)容是一個阻塞耗時過程,所以我們使用await實現(xiàn)協(xié)程切換)
(1)使用text()方法
async def func1(url,params): async with aiohttp.ClientSession() as session: async with session.get(url,params=params) as r: print(r.url) print(r.charset) #查看默認(rèn)編碼為utf-8 print(await r.text()) #不編碼,則是使用默認(rèn)編碼 使用encoding指定編碼
(2)使用read()方法,不進(jìn)行編碼,為字節(jié)形式
async def func1(url,params): async with aiohttp.ClientSession() as session: async with session.get(url,params=params) as r: print(r.url) print(await r.read())
(3)注意:text(),read()方法是把整個響應(yīng)體讀入內(nèi)存,如果你是獲取大量的數(shù)據(jù),請考慮使用”字節(jié)流“(StreamResponse)
5.特殊響應(yīng)內(nèi)容json(和上面一樣)
async def func1(url,params): async with aiohttp.ClientSession() as session: async with session.get(url,params=params) as r: print(r.url) print(r.charset) print(await r.json()) #可以設(shè)置編碼,設(shè)置處理函數(shù)
6.字節(jié)流形式獲取數(shù)據(jù)(不像text,read一次獲取所有數(shù)據(jù))注意:我們獲取的session.get()是Response對象,他繼承于StreamResponse
async def func1(url,params): async with aiohttp.ClientSession() as session: async with session.get(url,params=params) as r: print(await r.content.read(10)) #讀取前10字節(jié)
下面字節(jié)流形式讀取數(shù)據(jù),保存文件
async def func1(url,params,filename): async with aiohttp.ClientSession() as session: async with session.get(url,params=params) as r: with open(filename,"wb") as fp: while True: chunk = await r.content.read(10) if not chunk: break fp.write(chunk) tasks = [func1('https://www.ckook.com/forum.php',{"gid":6},"1.html"),]
注意:
async with session.get(url,params=params) as r: #異步上下文管理器 with open(filename,"wb") as fp: #普通上下文管理器
兩者的區(qū)別:
在于異步上下文管理器中定義了
__aenter__和__aexit__方法
異步上下文管理器指的是在enter
和exit
方法處能夠暫停執(zhí)行的上下文管理器
為了實現(xiàn)這樣的功能,需要加入兩個新的方法:__aenter__
和__aexit__
。這兩個方法都要返回一個 awaitable類型的值。
推文:異步上下文管理器async with和異步迭代器async for
7.自定義請求頭(和requests一樣)
async def func1(url,params,filename): async with aiohttp.ClientSession() as session: headers = {'Content-Type':'text/html; charset=utf-8'} async with session.get(url,params=params,headers=headers) as r: with open(filename,"wb") as fp: while True: chunk = await r.content.read(10) if not chunk: break fp.write(chunk)
8.自定義cookie
注意:對于自定義cookie,我們需要設(shè)置在ClientSession(cookies=自定義cookie字典),而不是session.get()中
class ClientSession: def __init__(self, *, connector=None, loop=None, cookies=None, headers=None, skip_auto_headers=None, auth=None, json_serialize=json.dumps, request_class=ClientRequest, response_class=ClientResponse, ws_response_class=ClientWebSocketResponse, version=http.HttpVersion11, cookie_jar=None, connector_owner=True, raise_for_status=False, read_timeout=sentinel, conn_timeout=None, timeout=sentinel, auto_decompress=True, trust_env=False, trace_configs=None):
使用:
cookies = {'cookies_are': 'working'} async with ClientSession(cookies=cookies) as session:
10.獲取網(wǎng)站的響應(yīng)狀態(tài)碼
async with session.get(url) as resp: print(resp.status)
11.查看響應(yīng)頭
resp.headers 來查看響應(yīng)頭,得到的值類型是一個dict:
resp.raw_headers 查看原生的響應(yīng)頭,字節(jié)類型
12.查看重定向的響應(yīng)頭(我們此時已經(jīng)到了新的網(wǎng)址,向之前的網(wǎng)址查看)
resp.history #查看被重定向之前的響應(yīng)頭
13.超時處理
默認(rèn)的IO操作都有5分鐘的響應(yīng)時間 我們可以通過 timeout 進(jìn)行重寫:
async with session.get('https://github.com', timeout=60) as r: ...
如果 timeout=None 或者 timeout=0 將不進(jìn)行超時檢查,也就是不限時長。
14.ClientSession 用于在多個連接之間(同一網(wǎng)站)共享cookie,請求頭等
async def func1(): cookies = {'my_cookie': "my_value"} async with aiohttp.ClientSession(cookies=cookies) as session: async with session.get("https://segmentfault.com/q/1010000007987098") as r: print(session.cookie_jar.filter_cookies("https://segmentfault.com")) async with session.get("https://segmentfault.com/hottest") as rp: print(session.cookie_jar.filter_cookies(https://segmentfault.com))
Set-Cookie: PHPSESSID=web2~d8grl63pegika2202s8184ct2q Set-Cookie: my_cookie=my_value Set-Cookie: PHPSESSID=web2~d8grl63pegika2202s8184ct2q Set-Cookie: my_cookie=my_value
我們最好使用session.cookie_jar.filter_cookies()獲取網(wǎng)站cookie,不同于requests模塊,雖然我們可以使用rp.cookies有可能獲取到cookie,但似乎并未獲取到所有的cookies。
async def func1(): cookies = {'my_cookie': "my_value"} async with aiohttp.ClientSession(cookies=cookies) as session: async with session.get("https://segmentfault.com/q/1010000007987098") as rp: print(session.cookie_jar.filter_cookies("https://segmentfault.com")) print(rp.cookies) #Set-Cookie: PHPSESSID=web2~jh4ouqoabvr4e72f87vtherkp6; Domain=segmentfault.com; Path=/ #首次訪問會獲取網(wǎng)站設(shè)置的cookie async with session.get("https://segmentfault.com/hottest") as rp: print(session.cookie_jar.filter_cookies("https://segmentfault.com")) print(rp.cookies) #為空,服務(wù)端未設(shè)置cookie async with session.get("https://segmentfault.com/newest") as rp: print(session.cookie_jar.filter_cookies("https://segmentfault.com")) print(rp.cookies) #為空,服務(wù)端未設(shè)置cookie
總結(jié):
當(dāng)我們使用rp.cookie時,只會獲取到當(dāng)前url下設(shè)置的cookie,不會維護(hù)整站的cookie
而session.cookie_jar.filter_cookies("https://segmentfault.com")會一直保留這個網(wǎng)站的所有設(shè)置cookies,含有我們在會話時設(shè)置的cookie,并且會根據(jù)響應(yīng)修改更新cookie。這個才是我們需要的
而我們設(shè)置cookie,也是需要在aiohttp.ClientSession(cookies=cookies)中設(shè)置
ClientSession 還支持 請求頭,keep-alive連接和連接池(connection pooling)
15.cookie的安全性
默認(rèn)ClientSession使用的是嚴(yán)格模式的 aiohttp.CookieJar. RFC 2109,明確的禁止接受url和ip地址產(chǎn)生的cookie,只能接受 DNS 解析IP產(chǎn)生的cookie??梢酝ㄟ^設(shè)置aiohttp.CookieJar 的 unsafe=True 來配置:
jar = aiohttp.CookieJar(unsafe=True) session = aiohttp.ClientSession(cookie_jar=jar)
16.控制同時連接的數(shù)量(連接池)
TCPConnector維持鏈接池,限制并行連接的總量,當(dāng)池滿了,有請求退出再加入新請求
async def func1(): cookies = {'my_cookie': "my_value"} conn = aiohttp.TCPConnector(limit=2) #默認(rèn)100,0表示無限 async with aiohttp.ClientSession(cookies=cookies,connector=conn) as session: for i in range(7,35): url = "https://www.ckook.com/list-%s-1.html"%i async with session.get(url) as rp: print('---------------------------------') print(rp.status)
限制同時打開限制同時打開連接到同一端點的數(shù)量((host, port, is_ssl) 三的倍數(shù)),可以通過設(shè)置 limit_per_host 參數(shù):
limit_per_host: 同一端點的大連接數(shù)量。同一端點即(host, port, is_ssl)完全相同
conn = aiohttp.TCPConnector(limit_per_host=30)#默認(rèn)是0
在協(xié)程下測試效果不明顯
17.自定義域名解析地址
我們可以指定域名服務(wù)器的 IP 對我們提供的get或post的url進(jìn)行解析:
from aiohttp.resolver import AsyncResolver resolver = AsyncResolver(nameservers=["8.8.8.8", "8.8.4.4"]) conn = aiohttp.TCPConnector(resolver=resolver)
18.設(shè)置代理
aiohttp支持使用代理來訪問網(wǎng)頁:
async with aiohttp.ClientSession() as session: async with session.get("http://python.org", proxy="http://some.proxy.com") as resp: print(resp.status)
當(dāng)然也支持需要授權(quán)的頁面:
async with aiohttp.ClientSession() as session: proxy_auth = aiohttp.BasicAuth('user', 'pass') #用戶,密碼 async with session.get("http://python.org", proxy="http://some.proxy.com", proxy_auth=proxy_auth) as resp: print(resp.status)
或者通過這種方式來驗證授權(quán):
session.get("http://python.org", proxy=http://user:pass@some.proxy.com)
19.post傳遞數(shù)據(jù)的方法
(1)模擬表單
payload = {'key1': 'value1', 'key2': 'value2'} async with session.post('http://httpbin.org/post', data=payload) as resp: print(await resp.text())
注意:data=dict的方式post的數(shù)據(jù)將被轉(zhuǎn)碼,和form提交數(shù)據(jù)是一樣的作用,如果你不想被轉(zhuǎn)碼,可以直接以字符串的形式 data=str 提交,這樣就不會被轉(zhuǎn)碼。
(2)post json
payload = {'some': 'data'} async with session.post(url, data=json.dumps(payload)) as resp:
其實json.dumps(payload)返回的也是一個字符串,只不過這個字符串可以被識別為json格式
(3)post 小文件
url = 'http://httpbin.org/post' files = {'file': open('report.xls', 'rb')} await session.post(url, data=files)
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)
如果將文件對象設(shè)置為數(shù)據(jù)參數(shù),aiohttp將自動以字節(jié)流的形式發(fā)送給服務(wù)器。
(4)post 大文件
aiohttp支持多種類型的文件以流媒體的形式上傳,所以我們可以在文件未讀入內(nèi)存的情況下發(fā)送大文件。
@aiohttp.streamer def file_sender(writer, file_name=None): with open(file_name, 'rb') as f: chunk = f.read(2**16) while chunk: yield from writer.write(chunk) chunk = f.read(2**16) # Then you can use `file_sender` as a data provider: async with session.post('http://httpbin.org/post', data=file_sender(file_name='huge_file')) as resp: print(await resp.text())
(5)從一個url獲取文件后,直接post給另一個url
r = await session.get('http://python.org') await session.post('http://httpbin.org/post',data=r.content)
(6)post預(yù)壓縮數(shù)據(jù)
在通過aiohttp發(fā)送前就已經(jīng)壓縮的數(shù)據(jù), 調(diào)用壓縮函數(shù)的函數(shù)名(通常是deflate 或 zlib)作為content-encoding的值:
async def my_coroutine(session, headers, my_data): data = zlib.compress(my_data) headers = {'Content-Encoding': 'deflate'} async with session.post('http://httpbin.org/post', data=data, headers=headers) pass
關(guān)于aiohttp怎么在python中使用就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,可以學(xué)到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。
當(dāng)前題目:aiohttp怎么在python中使用-創(chuàng)新互聯(lián)
網(wǎng)站網(wǎng)址:http://jinyejixie.com/article48/dhcohp.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站導(dǎo)航、做網(wǎng)站、軟件開發(fā)、App開發(fā)、服務(wù)器托管、企業(yè)網(wǎng)站制作
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容