日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 >

用PyCharm Profile分析异步爬虫效率

發(fā)布時間:2025/3/21 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 用PyCharm Profile分析异步爬虫效率 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

今天比較忙,水一下

下面的代碼來源于這個視頻里面提到的,github 的鏈接為:github.com/mikeckenned…

第一個代碼如下,就是一個普通的 for 循環(huán)爬蟲。原文地址。

import requests import bs4 from colorama import Foredef 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.textdef 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() 復(fù)制代碼

這段代碼跑完花了37s,然后我們用 pycharm 的 profiler 工具來具體看看哪些地方比較耗時間。

點擊Profile (文件名稱)

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

可以看到 get_html 這個方法占了96.7%的時間。這個程序的 IO 耗時達(dá)到了97%,獲取 html 的時候,這段時間內(nèi)程序就在那死等著。如果我們能夠讓他不要在那兒傻傻地等待 IO 完成,而是開始干些其他有意義的事,就能節(jié)省大量的時間。

稍微做一個計算,試用asyncio異步抓取,能將時間降低多少?

get_html這個方法耗時36.8s,一共調(diào)用了15次,說明實際上獲取一個鏈接的 html 的時間為36.8s / 15 = 2.4s。**要是全異步的話,獲取15個鏈接的時間還是2.4s。**然后加上get_title這個函數(shù)的耗時0.6s,所以我們估算,改進(jìn)后的程序?qū)⒖梢杂?3s 左右的時間完成,也就是性能能夠提升13倍。

再看下改進(jìn)后的代碼。原文地址。

import asyncio from asyncio import AbstractEventLoopimport aiohttp import requests import bs4 from colorama import Foredef main():# Create looploop = 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 ClientSessionurl = 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 htmldef 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 tasktitle = get_title(html, n)print(Fore.WHITE + f"Title found: {title}", flush=True)if __name__ == '__main__':main() 復(fù)制代碼

同樣的步驟生成profile 圖:

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

我的公眾號:全棧不存在的

總結(jié)

以上是生活随笔為你收集整理的用PyCharm Profile分析异步爬虫效率的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。