Heim  >  Artikel  >  Backend-Entwicklung  >  So wenden Sie gleichzeitige Programmierung in Python-Crawlern an

So wenden Sie gleichzeitige Programmierung in Python-Crawlern an

WBOY
WBOYnach vorne
2023-05-14 14:34:061282Durchsuche

Was ist gleichzeitige Programmierung? Unter gleichzeitiger Programmierung versteht man ein Programmdesign, das mehrere Vorgänge innerhalb eines Zeitraums ausführen kann. Dies äußert sich normalerweise darin, dass mehrere Aufgaben im Programm gleichzeitig gestartet werden und ausgeführt werden können, ohne sich gegenseitig zu beeinflussen. Der Vorteil der gleichzeitigen Programmierung besteht darin, dass sie die Programmleistung und Reaktionsfähigkeit verbessern kann.

Anwendung der gleichzeitigen Programmierung in Crawlern

Crawler-Programme sind typische E/A-intensive Aufgaben. Für E/A-intensive Aufgaben sind sowohl Multithreading als auch asynchrone E/A eine gute Wahl, da das Programm einen bestimmten Teil ausführt Wenn ein Teil des Programms aufgrund von E/A-Vorgängen blockiert ist, können andere Teile des Programms weiterhin ausgeführt werden, sodass wir nicht viel Zeit mit Warten und Blockieren verschwenden müssen.

Single-Threaded-Version

Sehen wir uns zunächst die Single-Threaded-Version des Crawler-Programms an. Dieses Crawler-Programm verwendet die Bibliothek requests, um JSON-Daten abzurufen und speichert das Bild lokal über die Funktion 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()

Auf macOS- oder Linux-Systemen können wir den Befehl time verwenden, um die Ausführungszeit des obigen Codes und die CPU-Auslastung zu verstehen, wie unten gezeigt. requests库获取 JSON 数据,并通过open函数将图片保存到本地。

"""
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()

在 macOS 或 Linux 系统上,我们可以使用time命令来了解上面代码的执行时间以及 CPU 的利用率,如下所示。

time python3 example04.py

下面是单线程爬虫代码在我的电脑上执行的结果。

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

这里我们只需要关注代码的总耗时为21.578秒,CPU 利用率为12%

多线程版本

我们使用之前讲到过的线程池技术,将上面的代码修改为多线程版本。

"""
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 example05.py

代码的执行结果如下所示:

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

异步I/O版本

我们使用aiohttp将上面的代码修改为异步 I/O 的版本。为了以异步 I/O 的方式实现网络资源的获取和写文件操作,我们首先得安装三方库aiohttpaiofile

time python3 example04.py

Das Folgende ist das Ergebnis des auf meinem Computer ausgeführten Single-Threaded-Crawler-Codes.

python3 example04.py 2,36s Benutzer 0,39s System 12% CPU 21,578 insgesamt

Hier müssen wir nur darauf achten, dass die Gesamtzeit, die der Code benötigt, 21,578 Sekunden beträgt, und die Die CPU-Auslastung beträgt 12 %.

Multithread-Version

Wir verwenden die zuvor erwähnte Thread-Pool-Technologie, um den obigen Code in eine Multithread-Version zu ändern.
rrreee

Führen Sie den unten gezeigten Befehl aus. Zeit Python3 Beispiel05.py

Wir verwendenaiohttpÄndern Sie den obigen Code in die asynchrone E/A-Version. Um Netzwerkressourcenerfassung und Dateischreibvorgänge bei asynchroner E/A zu erreichen, müssen wir zunächst die Drittanbieterbibliotheken aiohttp und aiofile installieren.

pip install aiohttp aiofile🎜🎜🎜Das Folgende ist die asynchrone E/A-Version des Crawler-Codes. 🎜rrreee🎜Führen Sie den unten gezeigten Befehl aus. 🎜🎜🎜time python3 example06.py🎜🎜🎜Das Ausführungsergebnis des Codes lautet wie folgt: 🎜🎜🎜python3 example06.py 0,92 s Benutzer 0,27 s System 290 % CPU 0,420 insgesamt🎜🎜🎜Im Vergleich zur Single-Threaded-Version von Das Crawler-Programm, mehr Die Ausführungszeit der Thread-Version und der asynchronen E/A-Version des Crawler-Programms wurde erheblich verbessert, und die asynchrone E/A-Version des Crawler-Programms schnitt am besten ab. 🎜

Das obige ist der detaillierte Inhalt vonSo wenden Sie gleichzeitige Programmierung in Python-Crawlern an. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:yisu.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen