Python爬蟲中的並發程式設計怎麼應用

WBOY
發布: 2023-05-14 14:34:06
轉載
1296 人瀏覽過

什麼是並發程式設計

並發程式設計是指在一個時間段內,能夠執行多個操作的程式設計,通常表現為程式中有多個任務同時啟動,可以運行並且相互之間不會產生影響。並發程式設計的好處是可以提高程式的效能和回應能力。

並發程式設計在爬蟲中的應用

爬蟲程式是典型的I/O 密集型任務,對於I/O 密集型任務來說,多執行緒和非同步I/O 都是很好的選擇,因為當程式的某個部分因I/O 操作阻塞時,程式的其他部分仍然可以運轉,這樣我們就不用在等待和阻塞中浪費大量的時間。

單執行緒版本

我們先來看單執行緒版本的爬蟲程式。這個爬蟲程式使用了requests庫來取得 JSON 數據,並透過open函數將圖片儲存到本機。

"""
example04.py - 单线程版本爬虫
"""
import os
import requests
def download_picture(url):
    filename = url[url.rfind('/') + 1:]
    resp = requests.get(url)
    if resp.status_code == 200:
        with open(f'images/beauty/{filename}', 'wb') as file:
            file.write(resp.content)
def main():
    if not os.path.exists('images/beauty'):
        os.makedirs('images/beauty')
    for page in range(3):
        resp = requests.get(f&#39;<https://image.so.com/zjl?ch=beauty&sn=>{page * 30}&#39;)
        if resp.status_code == 200:
            pic_dict_list = resp.json()[&#39;list&#39;]
            for pic_dict in pic_dict_list:
                download_picture(pic_dict[&#39;qhimg_url&#39;])
if __name__ == &#39;__main__&#39;:
    main()
登入後複製

在 macOS 或 Linux 系統上,我們可以使用time指令來了解上面程式碼的執行時間以及 CPU 的使用率,如下所示。

time python3 example04.py

#下面是單執行緒爬蟲程式碼在我的電腦上執行的結果。

python3 example04.py  2.36s user 0.39s system 12% cpu 21.578 total

這裡我們只需要關注程式碼的總耗時為21.578#這裡我們只需要關注程式碼的總耗時為21.578

秒,CPU 使用率為

12%

多執行緒版本

我們使用之前講過的執行緒池技術,將上面的程式碼修改為多執行緒版本。

"""
example05.py - 多线程版本爬虫
"""
import os
from concurrent.futures import ThreadPoolExecutor
import requests
def download_picture(url):
    filename = url[url.rfind(&#39;/&#39;) + 1:]
    resp = requests.get(url)
    if resp.status_code == 200:
        with open(f&#39;images/beauty/{filename}&#39;, &#39;wb&#39;) as file:
            file.write(resp.content)
def main():
    if not os.path.exists(&#39;images/beauty&#39;):
        os.makedirs(&#39;images/beauty&#39;)
    with ThreadPoolExecutor(max_workers=16) as pool:
        for page in range(3):
            resp = requests.get(f&#39;<https://image.so.com/zjl?ch=beauty&sn=>{page * 30}&#39;)
            if resp.status_code == 200:
                pic_dict_list = resp.json()[&#39;list&#39;]
                for pic_dict in pic_dict_list:
                    pool.submit(download_picture, pic_dict[&#39;qhimg_url&#39;])
if __name__ == &#39;__main__&#39;:
    main()
登入後複製

執行如下所示的命令。

time python3 example05.py

程式碼的執行結果如下所示:

python3 example05.py  2.65s user 0.40s system 95% cpu 3.193 total

非同步I/O版本我們使用aiohttp將上面的程式碼修改為非同步I/O 的版本。為了以非同步 I/O 的方式實現網路資源的取得和寫入檔案操作,我們首先得安裝三​​方函式庫

aiohttp

aiofile

pip install aiohttp aiofile

下面是非同步 I/O 版本的爬蟲程式碼。

"""
example06.py - 异步I/O版本爬虫
"""
import asyncio
import json
import os
import aiofile
import aiohttp
async def download_picture(session, url):
    filename = url[url.rfind(&#39;/&#39;) + 1:]
    async with session.get(url, ssl=False) as resp:
        if resp.status == 200:
            data = await resp.read()
            async with aiofile.async_open(f&#39;images/beauty/{filename}&#39;, &#39;wb&#39;) as file:
                await file.write(data)
async def main():
    if not os.path.exists(&#39;images/beauty&#39;):
        os.makedirs(&#39;images/beauty&#39;)
    async with aiohttp.ClientSession() as session:
        tasks = []
        for page in range(3):
            resp = await session.get(f&#39;<https://image.so.com/zjl?ch=beauty&sn=>{page * 30}&#39;)
            if resp.status == 200:
                pic_dict_list = (await resp.json())[&#39;list&#39;]
                for pic_dict in pic_dict_list:
                    tasks.append(asyncio.ensure_future(download_picture(session, pic_dict[&#39;qhimg_url&#39;])))
        await asyncio.gather(*tasks)
if __name__ == &#39;__main__&#39;:
    loop = asyncio.get_event_loop()
    loop.run_until_complete(main())
登入後複製
執行如下所示的命令。

time python3 example06.py

程式碼的執行結果如下所示:

python3 example06.py  0.92s user 0.27s system 290% cpu 0.420 total#########相對於單線程版本的爬蟲程序,多線程版本和異步I/O 版本的爬蟲程序在執行上的時間上有了顯著的提升,而且異步I /O 版本的爬蟲程序表現最佳。 ###

以上是Python爬蟲中的並發程式設計怎麼應用的詳細內容。更多資訊請關注PHP中文網其他相關文章!

相關標籤:
來源:yisu.com
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板