Comment appliquer la programmation simultanée dans les robots d'exploration Python

WBOY
Libérer: 2023-05-14 14:34:06
avant
1296 Les gens l'ont consulté

Qu'est-ce que la programmation simultanée

La programmation simultanée fait référence à une conception de programme qui peut effectuer plusieurs opérations sur une période donnée. Elle se manifeste généralement par le fait que plusieurs tâches du programme sont démarrées en même temps et peuvent s'exécuter sans s'influencer mutuellement. L'avantage de la programmation simultanée est qu'elle peut améliorer les performances et la réactivité du programme.

Application de la programmation simultanée dans les robots d'exploration

Les programmes Crawler sont des tâches typiques gourmandes en E/S, le multithread et les E/S asynchrones sont tous deux de bons choix, car lorsque le programme atteint une certaine partie. du programme est bloqué à cause d'opérations d'E/S, d'autres parties du programme peuvent toujours s'exécuter, de sorte que nous n'avons pas à perdre beaucoup de temps à attendre et à bloquer.

Version monothread

Regardons d'abord la version monothread du programme d'exploration. Ce programme d'exploration utilise la bibliothèque requests pour obtenir des données JSON et enregistre l'image localement via la fonction open. 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()
Copier après la connexion

在 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%

多线程版本

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

"""
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()
Copier après la connexion

执行如下所示的命令。

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

"""
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())
Copier après la connexion
Sur les systèmes macOS ou Linux, nous pouvons utiliser la commande time pour comprendre le temps d'exécution du code ci-dessus et l'utilisation du processeur, comme indiqué ci-dessous.

time python3 example04.py

Ce qui suit est le résultat du code du robot d'exploration monothread exécuté sur mon ordinateur.

python3 exemple04.py 2,36s utilisateur 0,39s système 12% cpu 21,578 total

Ici, nous devons seulement faire attention au temps total pris par le code pour être de 21,578 secondes, et le L'utilisation du processeur est de 12 %.

Version multithread

Nous utilisons la technologie de pool de threads mentionnée précédemment pour modifier le code ci-dessus en une version multithread.

rrreee
Exécutez la commande ci-dessous.

🎜time python3 example05.py🎜🎜🎜Le résultat de l'exécution du code est le suivant : 🎜🎜🎜python3 example05.py 2,65s utilisateur 0,40s système 95% cpu 3,193 total🎜🎜🎜Version E/S asynchrone 🎜🎜Nous useaiohttpModifiez le code ci-dessus vers la version d'E/S asynchrone. Afin de réaliser les opérations d'acquisition de ressources réseau et d'écriture de fichiers en E/S asynchrones, nous devons d'abord installer les bibliothèques tierces aiohttp et aiofile. 🎜🎜🎜pip install aiohttp aiofile🎜🎜🎜Ce qui suit est la version d'E/S asynchrone du code du robot. 🎜rrreee🎜Exécutez la commande ci-dessous. 🎜🎜🎜time python3 example06.py🎜🎜🎜Le résultat de l'exécution du code est le suivant : 🎜🎜🎜python3 example06.py 0,92s utilisateur 0,27s système 290% cpu 0,420 total🎜🎜🎜Par rapport à la version monothread de le programme d'exploration, plus Le temps d'exécution de la version threadée et de la version d'E/S asynchrones du programme d'exploration a été considérablement amélioré, et la version d'E/S asynchrones du programme d'exploration a été la plus performante. 🎜

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Étiquettes associées:
source:yisu.com
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal