如何组织多个Scrapy Spiders并在它们之间传递数据?

How to organize multiple Scrapy Spiders and pass data between them?

我有一个问题阻止我推进我的项目。 我会尽量解释清楚,但我对抓取还比较陌生。

现在 - 我想为网站 B 和网站 C 创建单独的蜘蛛(稍后使用它们直接抓取这些网站而不是通过网站 A)并以某种方式将从网站 A 抓取的数据作为参数传递给它们 - 但是“不知何故”部分是我需要你的帮助。

谢谢:)

编辑

Anwsering jqc - 因为我发布了我的问题,所以我做了一些开发 - 这是我到目前为止的代码。

class QuotesSpider(scrapy.Spider):
    name = 'Website A Spider'

    start_urls = ['start_url']

    def parse(self, response):
        self.logger.info('###### Link Parser ######')
        important_news = response.xpath('//div[contains(@class, "importantNews")]//div[contains(@class, "items")]/a')

        for news in important_news:
            yield {

                'link': news.xpath('./@href').get(),
                'title': news.xpath('.//span[contains(@class, "title")]/text()').get()

            }

            article_url = news.xpath('./@href').get()
            self.logger.info('FOLLOWING URL OF THE ARTICLE')

            if 'Website B' in article_url:
                yield response.follow(article_url, callback=self.parse_Website_B)
            else:
                pass

    def parse_Website_B(self, response):

            yield {
                'Website B article title': response.xpath('//p[contains(@class, "Header_desktopTextElement")]').get()

            }

不用担心未完成的解析,这是最不重要的部分:)

现在我正在创建单独的方法来解析特定网站,但我不知道这是否是最佳方法。

我想查看您正在尝试抓取的 URL。然后我可以做一些测试并尝试破译你的问题。 我可以给你一些提示,我不确定我是否理解你。 如果你想从 A 中抓取给定的 URLs,你可以直接这样做:

def parse_Website_B(self, response):

        yield {
            'Website B article title': response.xpath('//p[contains(@class, "Header_desktopTextElement")]').get()

        }

您只需提供链接,我会尝试使用 start_requests。查看文档 here.

如果您提供 URL,我们可以尝试其他方式。

干杯

我认为在您的情况下,在 spyder 文件中创建一个 URL 列表作为全局变量会容易得多,然后将其用作请求列表。

像这样:

from twisted.internet import reactor, defer
from scrapy.crawler import CrawlerRunner
from scrapy.utils.log import configure_logging
from scrapy import signals

URL_LIST = []
DATA_LIST = []

def store_url(*args, **kwargs):
    URL_LIST.append(kwargs['item'])

def store_data(*args, **kwargs):
    DATA_LIST.append(kwargs['item'])

class QuotesSpiderWebsiteA(scrapy.Spider):
    #Your code

class QuotesSpiderWebsiteB(scrapy.Spider):
    # etc...

if __name__ == '__main__':
    configure_logging()
    runner = CrawlerRunner()

    @defer.inlineCallbacks
    def crawl():
        crawler1 = runner.create_crawler(QuotesSpiderWebsiteA)
        crawler2 = runner.create_crawler(QuotesSpiderWebsiteB)
        crawler1.signals.connect(store_url, signals.item_scraped)
        crawler2.signals.connect(store_data, signals.item_scraped)
        yield runner.crawl(crawler1)
        yield runner.crawl(crawler2)
        reactor.stop()

    crawl()
    reactor.run()
    # the script will block here until the crawling is finished
    with open('output.json', 'w', encoding='utf8') as f:
        json.dump(DATA_LIST)