最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Python編程異步爬蟲之a(chǎn)iohttp模塊的基本用法

 更新時(shí)間:2024年03月29日 10:55:18   作者:Bruce_Liuxiaowei  
aiohttp?模塊是一個(gè)基于?asyncio?的?HTTP?客戶端和服務(wù)器框架,可以用于異步處理?HTTP?請(qǐng)求和響應(yīng),這篇文章給大家介紹Python編程異步爬蟲之a(chǎn)iohttp模塊的基本用法,感興趣的朋友一起看看吧

異步爬蟲—aiohttp的使用

基本介紹

asyncio模塊其內(nèi)部實(shí)現(xiàn)了對(duì)TCP、UDP、SSL協(xié)議的異步操作,但是對(duì)于HTTP請(qǐng)求來(lái)說(shuō),就需要用aiohttp實(shí)現(xiàn)了。

aiohttp是一個(gè)基于asyncio的異步HTTP網(wǎng)絡(luò)模塊,它既提供了服務(wù)端,又提供了客戶端。requests發(fā)起的是同步網(wǎng)絡(luò)請(qǐng)求,aiohttp則是異步。 aiohttp 模塊是一個(gè)基于 asyncio 的 HTTP 客戶端和服務(wù)器框架,可以用于異步處理 HTTP 請(qǐng)求和響應(yīng)。以下是一個(gè)簡(jiǎn)單的示例代碼展示 aiohttp 模塊的基本用法:

首先,你需要安裝 aiohttp 模塊:

pip install aiohttp

基本示例

接下來(lái),以下是一個(gè)簡(jiǎn)單的示例代碼,演示了如何使用 aiohttp 發(fā)送一個(gè)簡(jiǎn)單的 GET 請(qǐng)求并獲取響應(yīng):

import aiohttp
import asyncio

async def fetch(session, url):
    async with session.get(url) as response:
        return await response.text(), response.status

async def main():
    async with aiohttp.ClientSession() as session:
        html, status = await fetch(session, 'https://cuiqingcai.com')
        print(f'html:{html[:100]}....')
        print(f'status: {status}')

if __name__ == '__main__':
    loop = asyncio.get_event_loop()
    loop.run_until_complete(main())
    
  
 運(yùn)行結(jié)果如下:
 html:<!DOCTYPE html>
<html lang="zh-CN">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content....
status: 200

在這個(gè)示例中,我們定義了一個(gè) fetch 函數(shù)來(lái)發(fā)送 GET 請(qǐng)求并返回響應(yīng)文本,然后使用 main 函數(shù)調(diào)用 fetch 函數(shù)。最后,創(chuàng)建事件循環(huán)并運(yùn)行主函數(shù)。

由于網(wǎng)頁(yè)源碼過(guò)長(zhǎng),這里只截取了輸出的一部分,可以看到,成功獲取了網(wǎng)頁(yè)的源代碼及響應(yīng)狀態(tài)碼200,成功使用aiohttp通過(guò)異步方式完成了網(wǎng)頁(yè)爬取。當(dāng)然,這個(gè)操作用requests也可以做到。

URL參數(shù)設(shè)置

對(duì)于URL參數(shù)的設(shè)置,可以借助params參數(shù),傳入一個(gè)字典即可,示例如下:

import aiohttp
import asyncio
async def main():
    params = {'name': 'germey', 'age':25}
    async with aiohttp.ClientSession() as session:
        async with session.get('https://www.httpbin.org/get', params=params) as response:
            print(await response.text())
if __name__ == '__main__':
    asyncio.get_event_loop().run_until_complete(main())
  運(yùn)行結(jié)果如下:
  {
  "args": {
    "age": "25", 
    "name": "germey"
  }, 
  "headers": {
    "Accept": "*/*", 
    "Accept-Encoding": "gzip, deflate", 
    "Host": "www.httpbin.org", 
    "User-Agent": "Python/3.9 aiohttp/3.8.3", 
    "X-Amzn-Trace-Id": "Root=1-65ffa6c9-6d501fa57391d9fc1d7b5f28"
  }, 
  "origin": "58.21.224.175", 
  "url": "https://www.httpbin.org/get?name=germey&age=25"
}

這里看到,實(shí)際請(qǐng)求的URL為https://www.httpbin.org/get?name=germey&age=25,其中的參數(shù)對(duì)應(yīng)于params的內(nèi)容。

其他請(qǐng)求類型

aiohttp還支持其他請(qǐng)求類型,如POST、PUT、DELETE等,這和requests的使用方式有點(diǎn)類似,示例如下:

session.post('http://www.httpbin.org/post', data=b'data')
session.put('http://www.httpbin.org/put', data=b'data')
session.delete('http://www.httpbin.org/delete')
session.head('http://www.httpbin.org/get')
session.options('http://www.httpbin.org/get')
session.patch('http://www.httpbin.org/patch', data=b'data')

POST請(qǐng)求

當(dāng)使用 aiohttp 模塊時(shí),除了發(fā)送簡(jiǎn)單的 GET 請(qǐng)求之外,你還可以處理 POST 請(qǐng)求、設(shè)置請(qǐng)求頭、處理異常等。以下是一個(gè)稍微復(fù)雜一點(diǎn)的示例代碼,展示了如何發(fā)送 POST 請(qǐng)求并處理異常:

import aiohttp
import asyncio
async def main():
    data = {'name': 'germey', 'age':25}
    async with aiohttp.ClientSession() as session:
        async with session.post('https://www.httpbin.org/post', data=data) as response:
            print(await response.text())
if __name__ == '__main__':
    asyncio.get_event_loop().run_until_complete(main())
   運(yùn)行結(jié)果如下:
   {
  "args": {}, 
  "data": "", 
  "files": {}, 
  "form": {
    "age": "25", 
    "name": "germey"
  }, 
  "headers": {
    "Accept": "*/*", 
    "Accept-Encoding": "gzip, deflate", 
    "Content-Length": "18", 
    "Content-Type": "application/x-www-form-urlencoded", 
    "Host": "www.httpbin.org", 
    "User-Agent": "Python/3.9 aiohttp/3.8.3", 
    "X-Amzn-Trace-Id": "Root=1-65ffabc5-3bbf3cdb7cb413a3475ece45"
  }, 
  "json": null, 
  "origin": "58.21.224.175", 
  "url": "https://www.httpbin.org/post"
}

在上面的示例中,我們定義了一個(gè) fetch 函數(shù)來(lái)發(fā)送一個(gè)包含 JSON 數(shù)據(jù)的 POST 請(qǐng)求,并在發(fā)生異常時(shí)進(jìn)行處理。在 main 函數(shù)中調(diào)用 fetch 函數(shù),并根據(jù)返回的狀態(tài)碼和響應(yīng)文本輸出相應(yīng)信息。

通過(guò)這個(gè)示例,你可以進(jìn)一步了解如何使用 aiohttp 模塊處理 POST 請(qǐng)求和異常情況。你可以根據(jù)自己的需求進(jìn)行進(jìn)一步的定制和擴(kuò)展。希望這能幫助你更深入地理解 aiohttp 模塊的用法。

對(duì)于POST J SON數(shù)據(jù)提交,其對(duì)應(yīng)的請(qǐng)求頭中的Content-Type為application/json,我們只需將post方法里的data參數(shù)改成json即可,實(shí)例代碼如下:

import json
import aiohttp
import asyncio
async def main():
    data = {'name': 'germey', 'age': 25}
    async with aiohttp.ClientSession() as session:
        async with session.post('https://www.httpbin.org/post', json=data) as response:
            print(await response.text())
if __name__ == '__main__':
    print(asyncio.get_event_loop().run_until_complete(main()))
運(yùn)行結(jié)果如下:
    {
  "args": {}, 
  "data": "{\"name\": \"germey\", \"age\": 25}", 
  "files": {}, 
  "form": {}, 
  "headers": {
    "Accept": "*/*", 
    "Accept-Encoding": "gzip, deflate", 
    "Content-Length": "29", 
    "Content-Type": "application/json", 
    "Host": "www.httpbin.org", 
    "User-Agent": "Python/3.9 aiohttp/3.8.4", 
    "X-Amzn-Trace-Id": "Root=1-65ffc207-7d035c6f2b342778797881c9"
  }, 
  "json": {
    "age": 25, 
    "name": "germey"
  }, 
  "origin": "58.21.224.175", 
  "url": "https://www.httpbin.org/post"
}

響應(yīng)

我們可以用如下方法分別獲取其中的狀態(tài)碼、響應(yīng)頭、響應(yīng)體、響應(yīng)體二進(jìn)制內(nèi)容、響應(yīng)體JSON結(jié)果,實(shí)例代碼如下:

import aiohttp
import asyncio
async def main():
    data = {'name': 'germey', 'age': 25}
    async with aiohttp.ClientSession() as session:
        async with session.post('https://www.httpbin.org/post', data=data) as response:
            print('status:', response.status)
            print('headers:', response.headers)
            print('body:', await response.text())
            print('bytes:', await response.read())
            print('json:', await response.json())
if __name__ == '__main__':
    asyncio.get_event_loop().run_until_complete(main())
運(yùn)行結(jié)果如下:
status: 200
headers: <CIMultiDictProxy('Date': 'Sun, 24 Mar 2024 06:34:54 GMT', 'Content-Type': 'application/json', 'Content-Length': '510', 'Connection': 'keep-alive', 'Server': 'gunicorn/19.9.0', 'Access-Control-Allow-Origin': '*', 'Access-Control-Allow-Credentials': 'true')>
body: {
  "args": {}, 
  "data": "", 
  "files": {}, 
  "form": {
    "age": "25", 
    "name": "germey"
  }, 
  "headers": {
    "Accept": "*/*", 
    "Accept-Encoding": "gzip, deflate", 
    "Content-Length": "18", 
    "Content-Type": "application/x-www-form-urlencoded", 
    "Host": "www.httpbin.org", 
    "User-Agent": "Python/3.9 aiohttp/3.8.4", 
    "X-Amzn-Trace-Id": "Root=1-65ffc98e-153aad5f0e536d773cd978b4"
  }, 
  "json": null, 
  "origin": "58.21.224.175", 
  "url": "https://www.httpbin.org/post"
}
bytes: b'{\n  "args": {}, \n  "data": "", \n  "files": {}, \n  "form": {\n    "age": "25", \n    "name": "germey"\n  }, \n  "headers": {\n    "Accept": "*/*", \n    "Accept-Encoding": "gzip, deflate", \n    "Content-Length": "18", \n    "Content-Type": "application/x-www-form-urlencoded", \n    "Host": "www.httpbin.org", \n    "User-Agent": "Python/3.9 aiohttp/3.8.4", \n    "X-Amzn-Trace-Id": "Root=1-65ffc98e-153aad5f0e536d773cd978b4"\n  }, \n  "json": null, \n  "origin": "58.21.224.175", \n  "url": "https://www.httpbin.org/post"\n}\n'
json: {'args': {}, 'data': '', 'files': {}, 'form': {'age': '25', 'name': 'germey'}, 'headers': {'Accept': '*/*', 'Accept-Encoding': 'gzip, deflate', 'Content-Length': '18', 'Content-Type': 'application/x-www-form-urlencoded', 'Host': 'www.httpbin.org', 'User-Agent': 'Python/3.9 aiohttp/3.8.4', 'X-Amzn-Trace-Id': 'Root=1-65ffc98e-153aad5f0e536d773cd978b4'}, 'json': None, 'origin': '58.21.224.175', 'url': 'https://www.httpbin.org/post'}

可以看到,有些字段前需要加await,有些則不需要。其原則是,如果返回一個(gè)協(xié)程對(duì)象(如async修飾的方法),那么前面就要加await,具體可以看aiohttp的API,鏈接為https://docs.aiohttp.org/en/stable/client_reference.html。

超時(shí)設(shè)置

我們可以借助ClientTimeout對(duì)象設(shè)置超時(shí),例如要設(shè)置1秒的超時(shí)時(shí)間,可以這么實(shí)現(xiàn):

import asyncio
import aiohttp
async def main():
    timeout = aiohttp.ClientTimeout(total=2)
    async with aiohttp.ClientSession(timeout=timeout) as session:
        async with session.get('https://www.httpbin.org/get') as response:
            print('status:', response.status)
if __name__ == '__main__':
    asyncio.get_event_loop().run_until_complete(main())
運(yùn)行結(jié)果如下:
200

并發(fā)限制

由于aiohttp可以支持非常高的并發(fā)量,目標(biāo)網(wǎng)站可能無(wú)法在短時(shí)間內(nèi)響應(yīng),而且有瞬間將目標(biāo)網(wǎng)站爬掛掉的危險(xiǎn)。

一般情況下,可以借助asyncio的Semaphore來(lái)控制并發(fā)量,示例代碼如下:

import asyncio
import aiohttp
CONCURRENCY = 5
URL = 'https://www.baidu.com'
semaphore = asyncio.Semaphore(CONCURRENCY)
# session = None
async def scrape_api():
    async with semaphore:
        print('scraping',URL)
        async with session.get(URL) as response:
            await asyncio.sleep(1)
            return await response.text()
async def main():
    global session
    session = aiohttp.ClientSession()
    scrape_index_tasks = [asyncio.ensure_future(scrape_api()) for _ in range(100000)]
    await asyncio.gather(*scrape_index_tasks)
if __name__ == '__main__':
    asyncio.get_event_loop().run_until_complete(main())\
運(yùn)行結(jié)果:
scraping https://www.baidu.com
scraping https://www.baidu.com
scraping https://www.baidu.com
scraping https://www.baidu.com
scraping https://www.baidu.com
....

這里我們聲明CONCURRENCY(代表爬取的最大并發(fā)量)為5, 同時(shí)聲明爬取的目標(biāo)URL為百度。接著,借助Semaphore創(chuàng)建了一個(gè)信號(hào)量對(duì)象,將其賦值為semaphore,這樣就可以用它來(lái)控制最大并發(fā)量了。這里我們把semaphore直接放置在了對(duì)應(yīng)的爬取方法里,使用async with語(yǔ)句將semaphore作為上下文對(duì)象即可。信號(hào)量便可以控制進(jìn)入爬取的最大協(xié)程數(shù)量,即我們聲明的CONCURRENCY的值。在main方法里, 我們聲明10 000個(gè)task,將其傳遞給gather方法運(yùn)行,倘若不加以限制,那這10000個(gè)task會(huì)被同時(shí)執(zhí)行,并發(fā)數(shù)量相當(dāng)大。有了信號(hào)量的控制后,同時(shí)運(yùn)行的task數(shù)量最大會(huì)被控制5個(gè),這樣就能給aiohttp限制速度了。

到此這篇關(guān)于Python編程異步爬蟲之a(chǎn)iohttp模塊的基本用法的文章就介紹到這了,更多相關(guān)Python aiohttp使用內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • python超時(shí)重新請(qǐng)求解決方案

    python超時(shí)重新請(qǐng)求解決方案

    這篇文章主要介紹了python超時(shí)重新請(qǐng)求解決方案,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-10-10
  • Python中空格的轉(zhuǎn)義字符方式

    Python中空格的轉(zhuǎn)義字符方式

    這篇文章主要介紹了Python中空格的轉(zhuǎn)義字符方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-03-03
  • Python和OpenCV進(jìn)行多尺度模板匹配實(shí)現(xiàn)

    Python和OpenCV進(jìn)行多尺度模板匹配實(shí)現(xiàn)

    本文將實(shí)現(xiàn)如何將標(biāo)準(zhǔn)模板匹配擴(kuò)展到多尺度,使其可以處理模板和輸入圖像大小不同的匹配。具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-09-09
  • Python tkinter 下拉日歷控件代碼

    Python tkinter 下拉日歷控件代碼

    這篇文章主要介紹了Python tkinter 下拉日歷控件代碼,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-03-03
  • 如何使用?Python?Timedelta?月份計(jì)算日期

    如何使用?Python?Timedelta?月份計(jì)算日期

    在本篇文章中,我們將通過(guò)?timedelta?學(xué)習(xí)如何在?Python?中使用日期時(shí)間,?我們將了解如何計(jì)算當(dāng)前日期或任何其他日期六個(gè)月后的日期,本文通過(guò)示例代碼給大家介紹的非常詳細(xì),感興趣的朋友跟隨小編一起看看吧
    2023-10-10
  • Django def clean()函數(shù)對(duì)表單中的數(shù)據(jù)進(jìn)行驗(yàn)證操作

    Django def clean()函數(shù)對(duì)表單中的數(shù)據(jù)進(jìn)行驗(yàn)證操作

    這篇文章主要介紹了Django def clean()函數(shù)對(duì)表單中的數(shù)據(jù)進(jìn)行驗(yàn)證操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-07-07
  • pandas的唯一值、值計(jì)數(shù)以及成員資格的示例

    pandas的唯一值、值計(jì)數(shù)以及成員資格的示例

    今天小編就為大家分享一篇pandas的唯一值、值計(jì)數(shù)以及成員資格的示例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2018-07-07
  • python使用標(biāo)準(zhǔn)庫(kù)根據(jù)進(jìn)程名如何獲取進(jìn)程的pid詳解

    python使用標(biāo)準(zhǔn)庫(kù)根據(jù)進(jìn)程名如何獲取進(jìn)程的pid詳解

    Python有一套很有用的標(biāo)準(zhǔn)庫(kù)(standard library)。標(biāo)準(zhǔn)庫(kù)會(huì)隨著Python解釋器,一起安裝在你的電腦中的,所以下面這篇文章主要給大家介紹了關(guān)于python使用標(biāo)準(zhǔn)庫(kù)根據(jù)進(jìn)程名如何獲取進(jìn)程pid的相關(guān)資料,需要的朋友可以參考下。
    2017-10-10
  • Python 刪除文件每一行的行號(hào)思路解讀

    Python 刪除文件每一行的行號(hào)思路解讀

    有時(shí)候我們需要?jiǎng)h除代碼中的行號(hào),比如在把代碼復(fù)制到記事本中的時(shí)候,前邊的行號(hào)不刪除就沒(méi)辦法運(yùn)行,我們要手動(dòng)刪掉代碼段前的行號(hào),才能運(yùn)行代碼。如果有幾百行,就非常累,非常不爽,所以這種事還是要交給計(jì)算機(jī)去做
    2021-11-11
  • Python類和方法注釋規(guī)范說(shuō)明

    Python類和方法注釋規(guī)范說(shuō)明

    這篇文章主要介紹了Python類和方法注釋規(guī)范說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-06-06

最新評(píng)論

绥德县| 舒兰市| 普陀区| 冷水江市| 开鲁县| 朝阳县| 辽阳市| 依兰县| 三明市| 铜山县| 页游| 翼城县| 西乌| 通州区| 九龙城区| 南木林县| 德格县| 巢湖市| 棋牌| 内江市| 闵行区| 鄯善县| 彭山县| 日照市| 东乌珠穆沁旗| 莒南县| 会宁县| 锦屏县| 南丹县| 高邮市| 云浮市| 博客| 乐安县| 乌鲁木齐市| 北海市| 鹿泉市| 青阳县| 三穗县| 建昌县| 宜章县| 共和县|