溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

怎么使用PyCharm Profile分析異步爬蟲效率

發(fā)布時間:2022-03-24 14:19:31 來源:億速云 閱讀:157 作者:iii 欄目:web開發(fā)

這篇文章主要介紹“怎么使用PyCharm Profile分析異步爬蟲效率”的相關(guān)知識,小編通過實際案例向大家展示操作過程,操作方法簡單快捷,實用性強,希望這篇“怎么使用PyCharm Profile分析異步爬蟲效率”文章能幫助大家解決問題。

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

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('h2')
 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 工具來具體看看哪些地方比較耗時間。

點擊Profile (文件名稱)

怎么使用PyCharm Profile分析異步爬蟲效率

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

怎么使用PyCharm Profile分析異步爬蟲效率

可以看到 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,所以我們估算,改進后的程序?qū)⒖梢杂?3s 左右的時間完成,也就是性能能夠提升13倍。

再看下改進后的代碼。原文地址。

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('h2')
 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 圖:

怎么使用PyCharm Profile分析異步爬蟲效率

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

怎么使用PyCharm Profile分析異步爬蟲效率

關(guān)于“怎么使用PyCharm Profile分析異步爬蟲效率”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識,可以關(guān)注億速云行業(yè)資訊頻道,小編每天都會為大家更新不同的知識點。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI