Python クローラー: シングルスレッド、マルチスレッド、マルチプロセス

ここに画像の説明を挿入

序文

クローラーを使用してデータをクロールする場合、クロールされるデータの量が比較的多く、データを迅速に取得する必要がある場合は、シングルスレッド クローラーをマルチスレッド クローラーとして作成することを検討できます。その基本とコードの書き方を学びましょう。

1. プロセスとスレッド

プロセスは、実行中のプログラムのインスタンスとして理解できます。プロセスはリソースを所有する独立した単位ですが、スレッドは独立した単位ではありません。各スケジューリング プロセスのオーバーヘッドは比較的大きいため、この目的のためにスレッドが導入されています。プロセスには複数のスレッドを含めることができ、同時に複数のスレッドがプロセス内に存在することもできます。これらのスレッドはプロセスのリソースを共有し、スレッド切り替えの消費は非常にわずかです。したがって、オペレーティング システムにプロセスを導入する目的は、マルチチャネル プログラムの同時実行をより有効にし、リソース使用率とシステム スループットを向上させることであり、スレッドを導入する目的は、同時実行中にプログラムによって支払われる時間とスペースのオーバーヘッドを削減することです。実行し、オペレーティング システムの同時実行パフォーマンスを向上させます。
簡単な例で説明すると、図1のようにローカルコンピュータの「タスクマネージャー」を開きます。プロセスをジョブに例えて、そのジョブを実行するために 10 人を割り当てる場合、この 10 人は 10 個のスレッドになります。したがって、一定の範囲内では、マルチスレッドの効率はシングルスレッドの効率よりも高くなります。
ここに画像の説明を挿入
図 1. タスク マネージャー

2. Python のマルチスレッドとシングルスレッド

通常の学習プロセスでは、主にシングルスレッド クローラーを使用します。一般に、クロールされるリソースがそれほど大きくない場合は、単一のスレッドを使用できます。Python では、デフォルトでシングルスレッドです。これは単純に次のように理解されます。コードは順番に実行されます。たとえば、コードの最初の行が最初に実行され、次に 2 行目が実行される、というようになります。前の章で学んだ知識を単一のスレッドの形式で実践します。
例えば、Webサイトから画像を一括でダウンロードする場合、画像のダウンロードには時間がかかるため、シングルスレッドのままでは特に効率が悪く、ダウンロードに時間がかかります。ダウンロードを待ちます。時間を節約するために、現時点ではマルチスレッド方式を使用して画像をダウンロードすることを検討できます。
スレッディング モジュールは、Python でのマルチスレッド プログラミングに特化したモジュールで、スレッドをカプセル化し、より使いやすくなっています。例えば、コードを書くイベントとゲームをプレイするイベントの両方でマルチスレッドを使用する必要がある場合のコードは次のとおりです。

import threading
import time
# 定义第一个
def coding():
    for x in range(3):
        print('%s正在写代码\n' % x)
        time.sleep(1)
# 定义第二个
def playing():
    for x in range(3):
        print('%s正在玩游戏\n' % x)
        time.sleep(1)
# 如果使用多线程执行
def multi_thread():
    start = time.time()
    #  Thread创建第一个线程,target参数为函数命
    t1 = threading.Thread(target=coding)
    t1.start()  # 启动线程
    # 创建第二个线程
    t2 = threading.Thread(target=playing)
    t2.start()
    # join是确保thread子线程执行完毕后才能执行下一个线程
    t1.join()
    t2.join()
    end = time.time()
    running_time = end - start  
    print('总共运行时间 : %.5f 秒' % running_time)
# 执行
if __name__ == '__main__':
    multi_thread()  # 执行单线程

実行結果を図 2 に示します。
図 2. マルチスレッドの実行結果
図 2. マルチスレッドの実行結果
1 つのスレッドを実行するのにどれくらいの時間がかかるか、ケースのコードは次のとおりです。

import time
# 定义第一个
def coding():
    for x in range(3):
        print('%s正在写代码\n' % x)
        time.sleep(1)
# 定义第二个
def playing():
    start = time.time()
    for x in range(3):
        print('%s正在玩游戏\n' % x)
        time.sleep(1)
    end = time.time()
    running_time = end - start
    print('总共运行时间 : %.5f 秒' % running_time)
def single_thread():
    coding()
    playing()
# 执行
if __name__ == '__main__':
    single_thread()  # 执行单线程

実行結果を図 3 に示します。
ここに画像の説明を挿入
図 3. シングルスレッドの実行結果
上記のマルチスレッドとシングルスレッドの実行結果の後、コードの作成とゲームのプレイがマルチスレッドで同時に実行されていることがわかります。シングルスレッドでコードファースト ゲームをもう一度プレイします。時間的にはほんのわずかな差かもしれませんが、実行負荷が大きい場合にはマルチスレッドの方が時間がかかることがわかりますし、処理すべきタスクが少ない場合には、マルチスレッドの方が時間がかかることも分かります。場合によっては、単一のスレッドを作成するだけで十分な場合があります。

3 つ、シングルスレッドからマルチスレッドへ

ライブブロードキャストの画像クロールを例にとります。ケースコードは次のとおりです。

import requests
from lxml import etree
import time
import os

dirpath = '图片/'
if not os.path.exists(dirpath):
    os.mkdir(dirpath)  # 创建文件夹

header = {
    
    
    'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.162 Safari/537.36'
}
def get_photo():
    url = 'https://www.huya.com/g/4079/'  # 目标网站
    response = requests.get(url=url, headers=header)  # 发送请求
    data = etree.HTML(response.text)  # 转化为html格式
    return data

def jiexi():
    data = get_photo()
    image_url = data.xpath('//a//img//@data-original')
    image_name = data.xpath('//a//img[@class="pic"]//@alt')
    for ur, name in zip(image_url, image_name):
        url = ur.replace('?imageview/4/0/w/338/h/190/blur/1', '')
        title = name + '.jpg'
        response = requests.get(url=url, headers=header)  # 在此发送新的请求
        with open(dirpath + title, 'wb') as f:
            f.write(response.content)
        print("下载成功" + name)
        time.sleep(2)

if __name__ == '__main__':
        jiexi()

マルチスレッド クローラーに変更する必要がある場合は、main 関数のみを変更するだけで済みます。たとえば、クロール用の 4 つのスレッドを作成します。サンプル コードは次のとおりです。

if __name__ == "__main__":
    threads = []
    start = time.time()
    # 创建四个进程
    for i in range(1, 5):
        thread = threading.Thread(target=jiexi(), args=(i,))
        threads.append(thread)
        thread.start()
    for thread in threads:
        thread.join()
    end = time.time()
    running_time = end - start
    print('总共消耗时间 : %.5f 秒' % running_time)
    print("全部完成!")  # 主程序

4. おすすめの本

ここに画像の説明を挿入

この本では、Python3 Web クローラーの一般的なテクニックを紹介します。まず、Web ページの基礎知識を紹介し、次に urllib、Requests リクエスト ライブラリ、XPath、Beautiful Soup、その他の分析ライブラリを紹介し、次に Selenium による動的 Web サイトのクローリングと Scrapy クローラー フレームワークを紹介し、最後に Linux 基盤を紹介します。読者が独自に展開するのに便利 適切に作成されたクローラー スクリプト。
この本は主に Web クローリングに興味のある初心者向けです。
ここに画像の説明を挿入

おすすめ

転載: blog.csdn.net/weixin_51390582/article/details/132277083