如何从yield中获取结果并保存到文件?

2024-05-03 03:41:10 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在练习使用Scrapy webcrawler软件包,我有一个由两部分组成的问题,因为我有点想知道下一步该怎么做:

  1. 我有一个名为spider4Techcrunch.py的脚本,其中包含以下代码:

    import scrapy
    from scrapy import cmdline
    
    class TCSpider(scrapy.Spider):
        name = "techcrunch"
    
        def start_requests(self):
            urls = [
                "https://techcrunch.com/"
            ]
    
            for url in urls:
                yield scrapy.Request(url=url, callback=self.parse)
    
        def parse(self, response):
            SET_SELECTOR = ".post-block__title"
            output = "--BEGIN OUTPUT--"
            print(output)
            for data in response.css(SET_SELECTOR):
                print('--BEGIN DATA--')
                print(data)
                TITLE_SELECTOR = "a ::text"
                URL_SELECTOR = "a ::attr(href)"
                yield {
                    'title': data.css(TITLE_SELECTOR).extract_first(),
                    'url':data.css(URL_SELECTOR).extract_first(),
                }
    
    
    scrapy.cmdline.execute("scrapy runspider spider4Techcrunch.py".split())
    

    当我执行代码时,一切都正常工作并返回结果。我正在努力使用yield命令。如何从yield命令中提取KEY: VALUE"title": "url"的文本结果,以便逐行将结果保存到文本文件中

  2. 代码的最后一行,这是正确的执行方式吗?我只是觉得奇怪,我在同一个文件中调用自己来执行零碎的代码是否有最佳实践/更好的方法?(请记住,我希望该类可用于多个URL。)

    scrapy.cmdline.execute("scrapy runspider spider4Techcrunch.py".split())
    

Tags: 代码pyimportselfurldatatitleselector
3条回答

添加到执行脚本的方式:

而不是调用命令scrapy runspider spider4Techcrunch.py, 添加参数-O items.json

scrapy runspider spider4Techcrunch.py -O items.json将所有收益项目保存到JSON文件中

它将提供与@Georgiy的回答中所建议的类似的输出

如果要从命令行调用,更简洁的方法是从scrapy项目目录scrapy crawl <name-of-spider> -O items.json

在这种情况下,它将是scrapy crawl techcrunch -O item.json

您可以通过使用项目管道从产量中保存结果

步骤1)您必须像这样编写项目管道

class PricePipeline:
    vat_factor = 1.15

    def process_item(self, item, spider):
        if item.get('price'):
            if item.get('price_excludes_vat'):
                item['price'] = item['price'] * self.vat_factor
            return item
        else:
            raise DropItem("Missing price in %s" % item)

步骤2)您必须修改设置。py

ITEM_PIPELINES = {
    'your.pipelines.class': 300,
}

有关详细信息,请参阅https://docs.scrapy.org/en/latest/topics/item-pipeline.html

以脚本形式运行scrapy应用程序的首选方法-docs
您可以使用内置的feed exporters
在您的情况下,it解决方案如下(对于scrapy 2.1版):

import scrapy
from scrapy.crawler import CrawlerProcess

    class TCSpider(scrapy.Spider):
        name = "techcrunch"

        def start_requests(self):
            urls = [
                "https://techcrunch.com/"
            ]

            for url in urls:
                yield scrapy.Request(url=url, callback=self.parse)

        def parse(self, response):
            SET_SELECTOR = ".post-block__title"
            output = " BEGIN OUTPUT "
            print(output)
            for data in response.css(SET_SELECTOR):
                print(' BEGIN DATA ')
                print(data)
                TITLE_SELECTOR = "a ::text"
                URL_SELECTOR = "a ::attr(href)"
                yield {
                    'title': data.css(TITLE_SELECTOR).extract_first(),
                    'url':data.css(URL_SELECTOR).extract_first(),
                }

    process = CrawlerProcess(settings={
        "FEEDS": {
            "items.json": {"format": "json"},
            #"items.jl": {"format": "jsonlines"},

        },
    })

process.crawl(TCSpider)
process.start()

相关问题 更多 >