利用PyCharm Profile分析異步爬蟲(chóng)效率詳解
今天比較忙,水一下
下面的代碼來(lái)源于這個(gè)視頻里面提到的,github 的鏈接為:github.com/mikeckenned…(本地下載)
第一個(gè)代碼如下,就是一個(gè)普通的 for 循環(huán)爬蟲(chóng)。原文地址。
import requests
import bs4
from colorama import Fore
def main():
get_title_range()
print("Done.")
def get_html(episode_number: int) -> str:
print(Fore.YELLOW + f"Getting HTML for episode {episode_number}", flush=True)
url = f'https://talkpython.fm/{episode_number}'
resp = requests.get(url)
resp.raise_for_status()
return resp.text
def get_title(html: str, episode_number: int) -> str:
print(Fore.CYAN + f"Getting TITLE for episode {episode_number}", flush=True)
soup = bs4.BeautifulSoup(html, 'html.parser')
header = soup.select_one('h1')
if not header:
return "MISSING"
return header.text.strip()
def get_title_range():
# Please keep this range pretty small to not DDoS my site. ;)
for n in range(185, 200):
html = get_html(n)
title = get_title(html, n)
print(Fore.WHITE + f"Title found: {title}", flush=True)
if __name__ == '__main__':
main()
這段代碼跑完花了37s,然后我們用 pycharm 的 profiler 工具來(lái)具體看看哪些地方比較耗時(shí)間。
點(diǎn)擊Profile (文件名稱(chēng))

之后獲取到得到一個(gè)詳細(xì)的函數(shù)調(diào)用關(guān)系、耗時(shí)圖:

可以看到 get_html 這個(gè)方法占了96.7%的時(shí)間。這個(gè)程序的 IO 耗時(shí)達(dá)到了97%,獲取 html 的時(shí)候,這段時(shí)間內(nèi)程序就在那死等著。如果我們能夠讓他不要在那兒傻傻地等待 IO 完成,而是開(kāi)始干些其他有意義的事,就能節(jié)省大量的時(shí)間。
稍微做一個(gè)計(jì)算,試用asyncio異步抓取,能將時(shí)間降低多少?
get_html這個(gè)方法耗時(shí)36.8s,一共調(diào)用了15次,說(shuō)明實(shí)際上獲取一個(gè)鏈接的 html 的時(shí)間為36.8s / 15 = 2.4s。**要是全異步的話(huà),獲取15個(gè)鏈接的時(shí)間還是2.4s。**然后加上get_title這個(gè)函數(shù)的耗時(shí)0.6s,所以我們估算,改進(jìn)后的程序?qū)⒖梢杂?3s 左右的時(shí)間完成,也就是性能能夠提升13倍。
再看下改進(jìn)后的代碼。原文地址。
import asyncio
from asyncio import AbstractEventLoop
import aiohttp
import requests
import bs4
from colorama import Fore
def main():
# Create loop
loop = asyncio.get_event_loop()
loop.run_until_complete(get_title_range(loop))
print("Done.")
async def get_html(episode_number: int) -> str:
print(Fore.YELLOW + f"Getting HTML for episode {episode_number}", flush=True)
# Make this async with aiohttp's ClientSession
url = f'https://talkpython.fm/{episode_number}'
# resp = await requests.get(url)
# resp.raise_for_status()
async with aiohttp.ClientSession() as session:
async with session.get(url) as resp:
resp.raise_for_status()
html = await resp.text()
return html
def get_title(html: str, episode_number: int) -> str:
print(Fore.CYAN + f"Getting TITLE for episode {episode_number}", flush=True)
soup = bs4.BeautifulSoup(html, 'html.parser')
header = soup.select_one('h1')
if not header:
return "MISSING"
return header.text.strip()
async def get_title_range(loop: AbstractEventLoop):
# Please keep this range pretty small to not DDoS my site. ;)
tasks = []
for n in range(190, 200):
tasks.append((loop.create_task(get_html(n)), n))
for task, n in tasks:
html = await task
title = get_title(html, n)
print(Fore.WHITE + f"Title found: {title}", flush=True)
if __name__ == '__main__':
main()
同樣的步驟生成profile 圖:

可見(jiàn)現(xiàn)在耗時(shí)為大約3.8s,基本符合我們的預(yù)期了。

總結(jié)
以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,謝謝大家對(duì)腳本之家的支持。
- pycharm下打開(kāi)、執(zhí)行并調(diào)試scrapy爬蟲(chóng)程序的方法
- pycharm 使用心得(一)安裝和首次使用
- pycharm 使用心得(三)Hello world!
- Python、PyCharm安裝及使用方法(Mac版)詳解
- PyCharm使用教程之搭建Python開(kāi)發(fā)環(huán)境
- pycharm 使用心得(七)一些實(shí)用功能介紹
- pycharm 使用心得(九)解決No Python interpreter selected的問(wèn)題
- pycharm 使用心得(五)斷點(diǎn)調(diào)試
- python安裝教程 Pycharm安裝詳細(xì)教程
- pycharm 使用心得(二)設(shè)置字體大小
相關(guān)文章
Python面向?qū)ο笾瓷?自省機(jī)制實(shí)例分析
這篇文章主要介紹了Python面向?qū)ο笾瓷?自省機(jī)制,結(jié)合實(shí)例形式分析了Python面向?qū)ο蟪绦蛟O(shè)計(jì)中的反射/自省機(jī)制概念、原理及相關(guān)屬性操作技巧,需要的朋友可以參考下2018-08-08
windowns使用PySpark環(huán)境配置和基本操作
pyspark是Spark對(duì)Python的api接口,可以在Python環(huán)境中通過(guò)調(diào)用pyspark模塊來(lái)操作spark,這篇文章主要介紹了windowns使用PySpark環(huán)境配置和基本操作,感興趣的可以了解一下2021-05-05
利用Python判斷文件的幾種方法及其優(yōu)劣對(duì)比
任何的編程語(yǔ)言都離不開(kāi)文件操作,文件操作主要是幫助我們更好的創(chuàng)建打開(kāi)文件,讀取文件中的內(nèi)容、或是把我們想要保存的內(nèi)容寫(xiě)入文件中、或是管理文件目錄等等,下面這篇文章主要給大家介紹了關(guān)于利用Python判斷文件的幾種方法及其優(yōu)劣對(duì)比的相關(guān)資料,需要的朋友可以參考下2022-06-06
Python?turtle.shape()用法及實(shí)戰(zhàn)案例
turtle是Python自帶的一個(gè)小型的繪圖庫(kù),它可以幫助我們快速地繪制簡(jiǎn)單的圖形,這篇文章主要給大家介紹了關(guān)于Python?turtle.shape()用法及實(shí)戰(zhàn)案例的相關(guān)資料,需要的朋友可以參考下2024-03-03
python中快速進(jìn)行多個(gè)字符替換的方法小結(jié)
最近在用python給自己的seo工作提高效率和節(jié)省時(shí)間,發(fā)現(xiàn)python真的很不錯(cuò),可以完成很多事情。多個(gè)字符替換是大家可能都會(huì)遇到的一個(gè)問(wèn)題,昨天在工作中就碰到了這么一個(gè)問(wèn)題,所以想著記錄一下解決方案及其過(guò)程,方便以后參考。下面來(lái)一起看看吧。2016-12-12
使用Python讀取二進(jìn)制文件的實(shí)例講解
今天小編就為大家分享一篇使用Python讀取二進(jìn)制文件的實(shí)例講解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-07-07

