Scrapy:如何在一次爬虫运行中将抓取的数据存储在不同的json文件中?

Dan*_*iel 1 python scrapy web-scraping

我正在使用通用蜘蛛程序,并在该字段中包含多个网址列表start_urls

是否可以json为每个 URL 导出一个文件?

据我所知,只能设置一个特定输出文件的路径。

任何解决此问题的想法都会受到奖励!

编辑:这是我的蜘蛛类:

import scrapy
from scrapy.linkextractors import LinkExtractor
from scrapy.spiders import CrawlSpider, Rule

class MySpider(CrawlSpider):
    name = 'my_spider'
    start_urls =  start_urls = ['www.domain1.com','www.domain2.com', 
   'www.domain3.com']


    custom_settings = {
                'FEED_EXPORT_ENCODING': 'utf-8',
                'DEPTH_LIMIT': '1',
                'FEED_URI': 'file:///C:/path/to/result.json',
    }

    rules = (
        Rule(LinkExtractor(allow=r"abc"), callback='parse_item', follow=True),
    )

    def parse_item(self, response):
        all_text = response.xpath("//p/text()").getall()

        yield {
            "text": " ".join(all_text),
            "url": response.url,
        }
Run Code Online (Sandbox Code Playgroud)

小智 6

第一个选项

您可以将蜘蛛中的项目保存为Scrapy 教程,例如:

import scrapy
import json

DICT = {
    'https://quotes.toscrape.com/page/1/': 'domain1.json',
    'https://quotes.toscrape.com/page/2/': 'domain2.json',
}


class MydomainSpider(scrapy.Spider):
    name = "mydomain"
    start_urls = [
        'https://quotes.toscrape.com/page/1/',
        'https://quotes.toscrape.com/page/2/',
    ]

    def parse(self, response):
        filename = DICT[response.url]
        with open(filename, 'w') as fp:
            json.dump({"content": response.body.decode("utf-8")}, fp)
Run Code Online (Sandbox Code Playgroud)

DICT变量仅用于指定 JSON 文件名,但您也可以使用域作为文件名。

第二个选项

您可以尝试process_itempipelines.py如下方式使用:

from scrapy.exporters import JsonItemExporter


class SaveJsonPipeline:
    def process_item(self, item, spider):
       filename = item['filename']
       del item['filename']
       JsonItemExporter(open(filename, "wb")).export_item(item)
       return item
Run Code Online (Sandbox Code Playgroud)

item['filename']用于保存每个start_url. 您也需要设置items.py,例如:

import scrapy


class MydomainItem(scrapy.Item):
    filename = scrapy.Field()
    content = scrapy.Field()
Run Code Online (Sandbox Code Playgroud)

你的蜘蛛:

import scrapy
from ..items import MydomainItem


DICT = {
    'https://quotes.toscrape.com/page/1/': 'domain1.json',
    'https://quotes.toscrape.com/page/2/': 'domain2.json',
}


class MydomainSpider(scrapy.Spider):
    name = 'mydomain'
    allowed_domains = ['mydomain.com']
    start_urls = [
        'https://quotes.toscrape.com/page/1/',
        'https://quotes.toscrape.com/page/2/',
    ]

    def parse(self, response):
        item = MydomainItem()
        item["filename"] = DICT[response.url]
        item["content"] = response.body.decode("utf-8")
        yield item
Run Code Online (Sandbox Code Playgroud)

在运行之前,您需要在设置中添加管道。

ITEM_PIPELINES = {
    'myproject.pipelines.SaveJsonPipeline': 300,
}
Run Code Online (Sandbox Code Playgroud)