もうすぐ終わりますCeleryを使って爬虫類を加速させます!

6277 ワード

一、前に書く
前のブログでは、ネットワームという大量のネットリクエストを含むタスクについて言及しましたが、Celeryで加速して登ることができます.では、このブログでは、Celeryで私たちのワームを加速する方法を具体的に説明します.
二、知識の補充
1.class celery.group
groupというクラスは、並列に実行するタスクのセットを作成することを示しますが、タスクのセットは怠惰なので、実行して評価する必要があります.このクラスを理解するには、ドキュメントを表示するか、Pycharmで直接Ctrl+左ボタンを押すとソースコードを直接表示できます.次の図です.
 
 
 
 
Pythonリソース共有グループ:626017123
もちろん、ソースコードを直接見ても足りないので、自分で手を出したほうがいいです.まずtestを作成しますpy、コードは次のとおりです.
 1 from celery import Celery
 2 
 3 
 4 app = Celery("test", broker="redis://127.0.0.1:6379", backend="redis://127.0.0.1:6379")
 5 
 6 
 7 @app.task
 8 def add(x, y):
 9     return x + y
10 
11 
12 if __name__ == '__main__':
13     app.start()

次にCeleryサーバを実行し、test.pyのディレクトリの下にtest_を作成run.pyはテストに使用されます.コードは次のとおりです.
 1 from celery import group
 2 from .test import add
 3 
 4 
 5 lazy_group = group(add.s(2, 2), add.s(4, 4))
 6 print(type(lazy_group))
 7 result = lazy_group()
 8 print(result)
 9 print(type(result))
10 print(result.get())

Pycharmでtest_を実行run.py、得られた結果は以下の通りです.

fe54f453-eb9c-4b24-87e3-a26fab75967f

[4, 8]

ソースコードを表示すると、groupにタスクからなる反復可能なオブジェクトを入力できることがわかります.これでテストを行い、上のコードを少し変更します.
1 from celery import group
2 from CelerySpider.test import add
3 
4 
5 lazy_group = group(add.s(x, y) for x, y in zip([1, 3, 5, 7, 9], [2, 4, 6, 8, 10]))
6 result = lazy_group()
7 print(result)
8 print(result.get())

実行後、私たちが望む結果が得られました.
f03387f1-af00-400b-b58a-37901563251d
[3, 7, 11, 15, 19]

2.celer.result.collect()
Celeryにはタスク実行の結果やステータスなどを含むクラスresultがありますが、このクラスにはcollect()メソッドがあり、結果が返されたときに結果を収集できます.以前と同じ手順で、ソースコードを見てみましょう.
 
 
 
ここでソースコードを見ても霧が立ち込めているので、手書きコードを動かしてみてください.appを作成します.py、コードは次のとおりです.
 1 from celery import Celery, group, result
 2 
 3 
 4 app = Celery("test", broker="redis://127.0.0.1:6379", backend="redis://127.0.0.1:6379")
 5 
 6 
 7 @app.task(trail=True)
 8 def A(how_many):
 9     return group(B.s(i) for i in range(how_many))()
10 
11 
12 @app.task(trail=True)
13 def B(i):
14     return pow2.delay(i)
15 
16 
17 @app.task(trail=True)
18 def pow2(i):
19     return i ** 2
20 
21 
22 if __name__ == '__main__':
23     app.start()

サブタスクリストの実行後の結果を格納するために、タスクを設定するときにパラメータtrail=Trueが追加されていることがわかります.デフォルトですが、ここでは明示的に有効にします.Celeryを実行するサーバでappに入る.py兄弟ディレクトリ、pythonを入力し、次のコードを実行します.
>>> from app import A >>> res = A.delay(10) >>> [i[1] for i in res.collect() if isinstance(i[1], int)] [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

三、具体的な手順
1.プロジェクト構造
この爬虫類プロジェクトの基本文書は以下の通りです.
 
 
 
そのうちapp.py Celeryインスタンスの作成、celeryconfig.pyはCeleryが使用するプロファイルですtasks.pyの中には具体的なタスクがありますcrawl.pyは爬虫類のスクリプトで、Celeryサーバを開いた後、このファイルを実行します.
2.主なコード
まずはapp.py、コードは次のとおりです.config_from_object()メソッドはCeleryを構成するために使用され、入力されたパラメータはインポート可能なモジュールです.
 1 from celery import Celery
 2 
 3 
 4 app = Celery("spiders", include=["CelerySpider.tasks"])
 5 #       
 6 app.config_from_object("CelerySpider.celeryconfig")
 7 
 8 
 9 if __name__ == '__main__':
10     app.start()

次はtasksです.pyのコードで、Webページの送信要求と解析のコードが含まれています.
 1 import requests
 2 from lxml import etree
 3 from celery import group
 4 from CelerySpider.app import app
 5 
 6 
 7 headers = {
 8     "Cookie": "__cfduid=d5d815918f19b7370d14f80fc93f1f27e1566719058; UM_distinctid=16cc7bba92f7b6-0aac860ea9b9a7-7373e61-144000-16cc7bba930727; CNZZDATA1256911977=1379501843-1566718872-https%253A%252F%252Fwww.baidu.com%252F%7C1566718872; XSRF-TOKEN=eyJpdiI6InJvNVdZM0krZ1wvXC9BQjg3YUk5aGM1Zz09IiwidmFsdWUiOiI5WkI4QU42a0VTQUxKU2ZZelVxK1dFdVFydlVxb3g0NVpicEdkSGtyN0Uya3VkXC9pUkhTd2plVUtUTE5FNWR1aCIsIm1hYyI6Ijg4NjViZTQzNGRhZDcxNTdhMDZlMWM5MzI4NmVkOGZhNmRlNTBlYWM0MzUyODIyOWQ4ZmFhOTUxYjBjMTRmNDMifQ%3D%3D; doutula_session=eyJpdiI6IjFoK25pTG50azEwOXlZbmpWZGtacnc9PSIsInZhbHVlIjoiVGY2MU5Ob2pocnJsNVBLZUNMTWw5OVpjT0J6REJmOGVpSkZwNFlUZVwvd0tsMnZsaiszWEpTbEdyZFZ6cW9UR1QiLCJtYWMiOiIxZGQzNTJlNzBmYWE0MmQzMzQ0YzUzYmYwYmMyOWY3YzkxZjJlZTllNDdiZTlkODA2YmQ3YWRjNGRmZDgzYzNmIn0%3D",
 9     "Referer": "https://www.doutula.com/article/list/?page=1",
10     "UserAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36"
11 }
12 
13 
14 @app.task(trail=True)
15 def main(urls):
16     #    
17     return group(call.s(url) for url in urls)()
18 
19 
20 @app.task(trail=True)
21 def call(url):
22     #     
23     try:
24         res = requests.get(url, headers=headers)
25         parse.delay(res.text)
26     except Exception as e:
27         print(e)
28 
29 
30 @app.task(trail=True)
31 def parse(html):
32     #         
33     et = etree.HTML(html)
34     href_list = et.xpath('//*[@id="home"]/div/div[2]/a/@href')
35     result = []
36     for href in href_list:
37         href_res = requests.get(href, headers=headers)
38         href_et = etree.HTML(href_res.text)
39         src_list = href_et.xpath('//*[@class="artile_des"]/table/tbody/tr/td/a/img/@src') 
40         result.extend(src_list)
41     return result

最後はcrawlです.pyのコード:
 1 import time
 2 from CelerySpider.tasks import main
 3 
 4 
 5 start_time = time.time()
 6 
 7 
 8 url_list = ["https://www.doutula.com/article/list/?page={}".format(i) for i in range(1, 31)]
 9 res = main.delay(url_list)
10 all_src = []
11 for i in res.collect():
12     if isinstance(i[1], list) and isinstance(i[1][0], str):
13         all_src.extend(i[1])
14 
15 print("Src count: ", len(all_src))
16 
17 
18 end_time = time.time()
19 print("Cost time: ", end_time - start_time)

今回登ったサイトは表情パックサイト、url_Listは登るurlを表しています.ここでは30ページを登ってテストします.all_srcは、表情パケットのピクチャを格納するリソースリンクに用いられ、collect()法により這い出すリンクを抽出し、これらの表情パケットをダウンロードし、最後にダウンロードしたピクチャの数とプログラム全体にかかる時間を印刷する.
四、運行結果
Celeryサービスを実行する後、crawlを実行する.pyファイルには、次の情報が印刷されます.
 
 
 
爬虫類全体の動作が完了すると、時間が印刷されます.