亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

python aiohttp的使用詳解

系統(tǒng) 2446 0

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ù)用(默認開啟)可以加快整體的性能。

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)  #查看默認編碼為utf-8
   print(await r.text())  #不編碼,則是使用默認編碼  使用encoding指定編碼
          

(2)使用read()方法,不進行編碼,為字節(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__方法

python aiohttp的使用詳解_第1張圖片

異步上下文管理器指的是在 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.超時處理

默認的IO操作都有5分鐘的響應(yīng)時間 我們可以通過 timeout 進行重寫:

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

如果 timeout=None 或者 timeout=0 將不進行超時檢查,也就是不限時長。

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。

python aiohttp的使用詳解_第2張圖片

            
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~jh3ouqoabvr4e72f87vtherkp6; 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
          

python aiohttp的使用詳解_第3張圖片

總結(jié):

當我們使用rp.cookie時,只會獲取到當前url下設(shè)置的cookie,不會維護整站的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的安全性

默認ClientSession使用的是嚴格模式的 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維持鏈接池,限制并行連接的總量,當池滿了,有請求退出再加入新請求

            
async def func1():
 cookies = {'my_cookie': "my_value"}
 conn = aiohttp.TCPConnector(limit=2)  #默認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)#默認是0
          

在協(xié)程下測試效果不明顯

17.自定義域名解析地址

我們可以指定域名服務(wù)器的 IP 對我們提供的get或post的url進行解析:

            
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)
          

當然也支持需要授權(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
          

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯(lián)系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發(fā)表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 亚洲视频高清 | 国产一二三区在线观看 | 99这里只有 | 亚洲精品成人久久 | 一区二区网站 | 日本我不卡 | 久久午夜综合久久 | 成年人视频在线免费 | 欧美一级毛片一 | 国产精品久久久久无码av | 天天综合网天天综合色不卡 | 国产精品一区二区三区免费视频 | 色花堂国产精品第二页 | 久草视频播放 | 欧美日韩综合在线视频免费看 | 日夜操在线视频 | 成人在线免费网站 | 精品国产免费第一区二区三区日韩 | 欧美xxxxbbbb在线播放 | 美女视频黄的免费视频网页 | 久草视频福利在线观看 | 日本精品久久久久中文字幕 | 激情综合五月婷婷 | 久久精品六| 亚洲精品久久久久久婷婷 | 国产成人不卡 | 精品久久久久久久久久香蕉 | 日韩深夜视频 | 精品国产夜色在线 | 每日更新在线观看av | 国产亚洲精品一品区99热 | 日韩一区视频在线 | 四虎影院国产精品 | 亚洲国产精品一区二区久 | 九九热精品在线 | 日本黄色小视频在线观看 | 情欲综合网 | 亚洲最大成人网 色香蕉 | 国产综合婷婷 | 久久er国产精品免费观看2 | 久久青草免费91线频观看站街 |