scrapy 零碎的多处理

zbsbpyhn  于 2022-11-09  发布在  其他
关注(0)|答案(2)|浏览(152)

我正在尝试构建一个爬虫程序(使用Scrapy),它可以通过多处理从www.example.com启动蜘蛛程序main.py。
使用scrapy.crawler.CrawlerProcess启动第一个spider(cat_1),但不进行多处理:

crawler_settings = Settings()
crawler_settings.setmodule(default_settings)
runner = CrawlerProcess(settings=crawler_settings)
runner.crawl(cat_1)
runner.start(stop_after_crawl=True)

它工作正常,我有FEED处理的所有数据。
下一个网络程序需要第一个网络程序的结果,并进行多处理:
在加载第一个spider的结果后,我创建了一个URL列表,并将其发送给函数process_cat_2()

from multiprocessing import Process

def launch_crawler_cat_2(crawler, url):
    cat_name = url[0]
    cat_url = url[1]

    runner.crawl(crawler, cat_name, cat_url)

def process_cat_2(url_list):
    nb_spiders = len(url_list)
    list_process = [None] * nb_spiders

    while(url_list):
        for i in range(nb_spiders):
            if not (list_process[i] and list_process[i].is_alive()):
                list_process[i] = Process(target=launch_crawler_cat_2, args=(cat_2, url_list.pop(0)))
                list_process[i].start()
                # break

    # Wait all thread end
    for process in list_process:
        if process:
            # process.start()
            process.join()

问题是runner.crawl(crawler, cat_name, cat_url)(在cat_2中)不抓取任何内容:

2021-10-07 17:20:38 [scrapy.extensions.logstats] INFO: Crawled 0 pages (at 0 pages/min), scraped 0 items (at 0 items/min)

而且我不知道如何使用现有的twisted.internet.reactor,所以要避免这个错误:

twisted.internet.error.ReactorNotRestartable

使用时:

def launch_crawler_cat_2(crawler, url):
    cat_name = url[0]
    cat_url = url[1]

    runner.crawl(crawler, cat_name, cat_url)
    runner.start()

如何使用现有的reactor对象启动新的蜘蛛?

jhiyze9q

jhiyze9q1#

这里有一个解决方案,我可以运行多个蜘蛛,其中一些蜘蛛需要以前的结果,一些蜘蛛与多处理。
在不同的进程中初始化每个Crawler:

import sys
import json
import pandas as pd
from multiprocessing import Process

## Scrapy

from scrapy.crawler import CrawlerProcess
from scrapy.settings import Settings

## Spiders & settings

from myproject.spiders.cat_1 import cat_1
from myproject.spiders.cat_2 import cat_2
from myproject import settings as default_settings

## Init crawler

crawler_settings = Settings()
crawler_settings.setmodule(default_settings)

# runner = CrawlerRunner(settings=default_settings)

runner = CrawlerProcess(settings=crawler_settings)

def launch_crawler_cat_2(crawler, url):
    process = CrawlerProcess(crawler_settings)
    process.crawl(crawler,url[0],url[1])
    process.start(stop_after_crawl=True)

def process_cat_2(url_list):
    nb_spiders = 5
    list_process = [None] * nb_spiders

    while(url_list):
        for i in range(nb_spiders):
            if not (list_process[i] and list_process[i].is_alive()):
                list_process[i] = Process(target=launch_crawler_cat_2, args=(cat_2, url_list.pop(0)))
                list_process[i].start()
                break

    # Wait all thread end
    for process in list_process:
        if process:
            process.join()

def crawl_cat_1():
    process = CrawlerProcess(crawler_settings)
    process.crawl(cat_1)
    process.start(stop_after_crawl=True)

if __name__=="__main__":

    ## Scrape cat_1
    process_cat_1 = Process(target=crawl_cat_1)
    process_cat_1.start()
    process_cat_1.join()

    ##########################################################################
    ########## LOAD cat_1 RESULTS
    try:
        with open('./cat_1.json', 'r+', encoding="utf-8") as f:
            lines = f.readlines()
            lines = [json.loads(line) for line in lines]
            df_cat_1 = pd.DataFrame(lines)
    except:
        df_cat_1 = pd.DataFrame([])

    print(df_cat_1)
    if df_cat_1.empty:
        sys.exit('df_cat_1 empty DataFrame')

    df_cat_1['cat_1_tuple'] = list(zip(df_cat_1.cat_name, df_cat_1.cat_url))
    df_cat_1_tuple_list = df_cat_1.cat_1_tuple.tolist()

    process_cat_2(df_cat_1_tuple_list)
1tuwyuhd

1tuwyuhd2#

嗯..我找到了一个解决方案,运行多个蜘蛛,多次使用CrawlerRunner推荐的文档https://docs.scrapy.org/en/latest/topics/practices.html#run-scrapy-from-a-script
还有另一个Scrapy实用程序,它提供了对爬行过程的更多控制:scrapy.crawler.CrawlerRunner.这个类是一个简单的 Package 器,它封装了一些简单的帮助器来运行多个爬虫程序,但是它不会以任何方式启动或干扰现有的React器。
使用这个类,React器应该在调度蜘蛛后显式运行。如果你的应用程序已经在使用Twisted,并且你想在同一个React器中运行Scrapy,建议你使用CrawlerRunner而不是CrawlerProcess。
下面是我的解决方案:https://stackoverflow.com/a/71643677/18604520

相关问题