同期、マルチプロセス、およびコルーチンでのクローラーの比較

Pythonを使用してクローラーをコンパイルし、同期、マルチプロセス、コルーチンでそれぞれ実装されるWeibo検索の上位10タイトルを取得します。それぞれの実装方法の違いを比較します。もちろん、実行効率も大きく異なります。

1.同期を使用して、ホット検索タイトルを1つずつクロールして出力します。

この方法は最も単純で、1つずつクロールして処理し、効率が最も低くなります。

import time
import requests
from bs4 import BeautifulSoup

def get_title(url):
    try:
    	#由于新浪微博具有反爬措施,需要一个header字典储存cookie信息,可在网站的页面按f12查看并复制。
        header={
    
    "user-agent":"Chrome/78.0.3904.108",'cookie':'SUB=_2AkMqIoz1f8PxqwJRmPAVxWPnaIpyyQnEieKcfn0uJRMxHRl-yT9kqkAFtRB6AaKiGn7WbCVQVtWDseW_5JZsJ0NoICGr; SUBP=0033WrSXqPxfM72-Ws9jqgMF55529P9D9WWJrDJ8H0hrSpRG9GpmEzGF; SINAGLOBAL=5229331688388.405.1568539601424; login_sid_t=1a1165955454339327bdef141125e35c; cross_origin_proto=SSL; Ugrow-G0=5c7144e56a57a456abed1d1511ad79e8; YF-V5-G0=8c1ea32ec7cf68ca3a1513783c276b8c; _s_tentry=-; wb_view_log=1280*7201.5; Apache=2516595840555.2446.1585651161757; ULV=1585651161764:5:1:1:2516595840555.2446.1585651161757:1582956310594; WBStorage=42212210b087ca50|undefined; YF-Page-G0=c704b1074605efc315869695a91e5996|1585653703|1585653701'}
        r=requests.get(url,timeout=30,headers=header)#爬取页面信息
        r.encoding=r.apparent_encoding#获得编码方式
        soup=BeautifulSoup(r.text,'html.parser')#使用Beautiful处理
        print(soup.find(attrs={
    
    'class':'title'}).string)#输出含有属性class:'title'的标签的非属性字符串,即页面的标题
    except:
        print('error')
#页面链接列表
urls=[
    'https://weibo.com/ttarticle/p/show?id=2309404488307177292254',
    'https://weibo.com/ttarticle/p/show?id=2309404488460353274040',
    'https://weibo.com/ttarticle/p/show?id=2309354488485582012495',
    'https://weibo.com/ttarticle/p/show?id=2309354488485540069723',
    'https://weibo.com/ttarticle/p/show?id=2309354488485808505228',
    'https://weibo.com/ttarticle/p/show?id=2309404488184535843057',
    'https://weibo.com/ttarticle/p/show?id=2309354488519753007179',
    'https://weibo.com/ttarticle/p/show?id=2309354488514216526214',
    'https://weibo.com/ttarticle/p/show?id=2309354488464673406980',
    'https://weibo.com/ttarticle/p/show?id=2309354488533355135102'
    ]
#逐个执行
def main(urls):
    for url in urls:
        get_title(url)

start=time.time()
main(urls)
end=time.time()
print('run time is %.5f'%(end-start))#输出运行所花费的时间

Weiboホット検索のトップ10タイトルを取得するために実行すると、実行時間は7.73秒であることがわかりますここに画像の説明を挿入

次に、マルチプロセスメソッドを使用してクローラーを実装します

ここで、mutiprocessing.Poolを使用してマルチプロセスクローラーを実装します。コンピューターには4つのコアがあるため、プロセスプールを4に設定します(p = Pool(4))

import multiprocessing
from multiprocessing import Pool
import time
import requests
from bs4 import BeautifulSoup

def get_title(url):
    try:
        header={
    
    "user-agent":"Chrome/78.0.3904.108",'cookie':'SUB=_2AkMqIoz1f8PxqwJRmPAVxWPnaIpyyQnEieKcfn0uJRMxHRl-yT9kqkAFtRB6AaKiGn7WbCVQVtWDseW_5JZsJ0NoICGr; SUBP=0033WrSXqPxfM72-Ws9jqgMF55529P9D9WWJrDJ8H0hrSpRG9GpmEzGF; SINAGLOBAL=5229331688388.405.1568539601424; login_sid_t=1a1165955454339327bdef141125e35c; cross_origin_proto=SSL; Ugrow-G0=5c7144e56a57a456abed1d1511ad79e8; YF-V5-G0=8c1ea32ec7cf68ca3a1513783c276b8c; _s_tentry=-; wb_view_log=1280*7201.5; Apache=2516595840555.2446.1585651161757; ULV=1585651161764:5:1:1:2516595840555.2446.1585651161757:1582956310594; WBStorage=42212210b087ca50|undefined; YF-Page-G0=c704b1074605efc315869695a91e5996|1585653703|1585653701'}
        r=requests.get(url,timeout=30,headers=header)
        r.encoding=r.apparent_encoding
        soup=BeautifulSoup(r.text,'html.parser')
        print(soup.find(attrs={
    
    'class':'title'}).string)
    except:
        print('error...')

urls=[
    'https://weibo.com/ttarticle/p/show?id=2309404488307177292254',
    'https://weibo.com/ttarticle/p/show?id=2309404488460353274040',
    'https://weibo.com/ttarticle/p/show?id=2309354488485582012495',
    'https://weibo.com/ttarticle/p/show?id=2309354488485540069723',
    'https://weibo.com/ttarticle/p/show?id=2309354488485808505228',
    'https://weibo.com/ttarticle/p/show?id=2309404488184535843057',
    'https://weibo.com/ttarticle/p/show?id=2309354488519753007179',
    'https://weibo.com/ttarticle/p/show?id=2309354488514216526214',
    'https://weibo.com/ttarticle/p/show?id=2309354488464673406980',
    'https://weibo.com/ttarticle/p/show?id=2309354488533355135102'
    ]

def main(urls):
    p=Pool(4)#设置进程池为4
    for url in urls:
        p.apply_async(get_title,args=[url])#创建多个进程,并发执行
    p.close()
    p.join()# 运行完所有子进程才能顺序运行后续程序
#把实际执行功能的代码封装成一个函数,然后加入到if __name__ == '__main__':中执行,否则将报错。
if __name__=='__main__':
    start=time.time()
    main(urls)
    end=time.time()
    print('run time is %.5f'%(end-start))

ここで、Windows環境では、関数を実際に実行するコードを関数にカプセル化してからif __name__=='__main__'、実行のために追加する必要があることに注意してください。そうしないと、次のようにエラーRuntimeError:reeze_support()が報告されます。

    An attempt has been made to start a new process before the
    current process has finished its bootstrapping phase.

    This probably means that you are not using fork to start your
    child processes and you have forgotten to use the proper idiom
    in the main module:

        if __name__ == '__main__':
            freeze_support()
            ...

    The "freeze_support()" line can be omitted if the program
    is not going to be frozen to produce an executable.

Windowsではフォーク呼び出しがないため、このエラーはLinuxでは表示されません。
マルチプロセスを使用したクローラーの実行結果は次のとおりです。
実行時間は4.56秒であり、効率が向上していることがわかります。ここに画像の説明を挿入
次の図は、マルチプロセスクローラーの実行フローチャートを示しています(写真はインターネットからのものです)ここに画像の説明を挿入

3、コルーチンの使い方

リクエストは待機できず、待機することもできないため、公式のaiohttpライブラリは、非同期Webページリクエストやその他の機能を実装するために特別に提供されています。リクエストライブラリの非同期バージョンと見なすことができ、手動でインストールする必要があります。インストールコマンド:pip install aiohttp

import aiohttp
import asyncio
import time
from bs4 import BeautifulSoup
header={
    
    "user-agent":"Chrome/78.0.3904.108",'cookie':'SUB=_2AkMqIoz1f8PxqwJRmPAVxWPnaIpyyQnEieKcfn0uJRMxHRl-yT9kqkAFtRB6AaKiGn7WbCVQVtWDseW_5JZsJ0NoICGr; SUBP=0033WrSXqPxfM72-Ws9jqgMF55529P9D9WWJrDJ8H0hrSpRG9GpmEzGF; SINAGLOBAL=5229331688388.405.1568539601424; login_sid_t=1a1165955454339327bdef141125e35c; cross_origin_proto=SSL; Ugrow-G0=5c7144e56a57a456abed1d1511ad79e8; YF-V5-G0=8c1ea32ec7cf68ca3a1513783c276b8c; _s_tentry=-; wb_view_log=1280*7201.5; Apache=2516595840555.2446.1585651161757; ULV=1585651161764:5:1:1:2516595840555.2446.1585651161757:1582956310594; WBStorage=42212210b087ca50|undefined; YF-Page-G0=c704b1074605efc315869695a91e5996|1585653703|1585653701'}
sem=asyncio.Semaphore(10)# 信号量,控制协程数,防止爬的过快
async def get_title(url,header):
    async with sem:
        async with aiohttp.ClientSession() as session:
            async with session.request('GET',url,headers=header) as result:
                try:
                    text=await result.text()
                    soup=BeautifulSoup(text,'html.parser')
                    print(soup.find(attrs={
    
    'class':'title'}).string)
                except:
                    print('error...')

urls=[
    'https://weibo.com/ttarticle/p/show?id=2309404488307177292254',
    'https://weibo.com/ttarticle/p/show?id=2309404488460353274040',
    'https://weibo.com/ttarticle/p/show?id=2309354488485582012495',
    'https://weibo.com/ttarticle/p/show?id=2309354488485540069723',
    'https://weibo.com/ttarticle/p/show?id=2309354488485808505228',
    'https://weibo.com/ttarticle/p/show?id=2309404488184535843057',
    'https://weibo.com/ttarticle/p/show?id=2309354488519753007179',
    'https://weibo.com/ttarticle/p/show?id=2309354488514216526214',
    'https://weibo.com/ttarticle/p/show?id=2309354488464673406980',
    'https://weibo.com/ttarticle/p/show?id=2309354488533355135102'
    ]

def main(urls,header):
    loop=asyncio.get_event_loop()#获取事件循环
    tasks=[get_title(url,header) for url in urls]#生成任务列表
    loop.run_until_complete(asyncio.wait(tasks))#激活协程

if __name__=='__main__':
    start=time.time()
    main(urls,header)
    end=time.time()
    print('run time is %.5f'%(end-start))

実装の結果は次のとおりです
。0.82秒のみが使用され、非常に効率的です。ここに画像の説明を挿入
説明:
1、semaphore同時に作業コルーチン同期ツールの数を制限することである
コルーチンで、2aiohttpウェブページを要求トンClientSession()reques

非同期クローラーは、単一のスレッドを使用して(つまり、イベントループのみを作成し、すべてのタスクをイベントループに追加する)、複数のタスクを同時に処理するという点で、マルチプロセスクローラーとは異なります。タスクのポーリング後、時間のかかる操作(URLの要求など)が発生すると、タスクは一時停止され、次のタスクが実行されます。以前に一時停止されたタスクのステータスが更新された場合(Webページの応答の取得など) )、それは目覚め、プログラムは前回中断されたところから実行を続けます。途中で不要な待ち時間を大幅に短縮
——————————————
著作権表示:この記事は、CSDNブロガー「SL_World」のオリジナル記事であり、CC 4.0BY-SA著作権表示に準拠しています。 、転載のために元のソースとこのステートメントへのリンクを添付してください。
元のリンク:https://blog.csdn.net/SL_World/article/details/86633611

次の図は、コルーチンクローラーの実行フローチャートを示しています(写真はインターネットからのものです)ここに画像の説明を挿入

おすすめ

転載: blog.csdn.net/qq_44371305/article/details/105229980