You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Scrapy爬虫完成抓取时将结束时间写入JSON文件

Scrapy爬虫结束时间写入JSON实现方案

首先明确核心逻辑:爬虫结束时间是爬虫完全停止后才会生成的全局值,无法在单条数据采集的parse_items阶段直接获取,需要结合Spider的生命周期方法和Pipeline配合实现。

一、先修改CrawlSpider代码,解决startUrl、productUrl获取+结束时间生成的问题

from scrapy.http import Request
from scrapy.spiders import CrawlSpider, Rule
from scrapy.linkextractors import LinkExtractor
from ebaycomp.items import EbayItem
from datetime import datetime

class EbaySpider(CrawlSpider):
    name = 'spider'
    allowed_domains = ['ebay.co.uk']
    start_urls = [
        'https://www.ebay.co.uk/sch/49831/i.html?_from=R40&_nkw=chain+and+sprocket+kit&LH_ItemCondition=1000&rt=nc&LH_PrefLoc=1',
        'https://www.ebay.co.uk/sch/177771/i.html?_from=R40&_nkw=motorcycle+air+filter&LH_ItemCondition=1000&rt=nc&LH_PrefLoc=1'
    ]

    rules = [
        Rule(
            LinkExtractor(
                allow=('.*'),
                restrict_xpaths=[
                    '//a[@class="s-item__link"][1]',
                    '//a[@class="s-item__link"][2]',
                    '//a[@class="s-item__link"][3]'
                ]
            ),
            callback='parse_items',
            follow=True,
            # 传递父请求的meta到子请求,保留start_url标记
            process_request=lambda request, response: request.replace(meta=response.meta)
        )
    ]

    # 重写起始请求方法,给每个起始列表页带上start_url标记
    def start_requests(self):
        for url in self.start_urls:
            yield Request(url, meta={"start_url": url})

    def parse_items(self, response):
        scrapedItem = EbayItem()
        # 从meta中取当前商品对应的起始列表页URL
        scrapedItem['startUrl'] = response.meta.get("start_url")
        # 当前页面URL就是商品详情页URL
        scrapedItem['productUrl'] = response.url
        scrapedItem['productTitle'] = response.xpath('//h1/text()').get()
        scrapedItem['productPrice'] = response.xpath('//span[@itemprop="price"]/text()').get()
        # 此处无需赋值timeClosed,后续在Pipeline统一处理
        return scrapedItem

    # 爬虫关闭时自动触发,生成结束时间存储到spider实例
    def closed(self, reason):
        self.end_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
        self.close_reason = reason

二、修改JsonWriterPipeline,按需求写入结束时间

场景1:所有商品条目都附带爬虫结束时间(适合小数据量采集)

需要先把所有采集到的item暂存在内存里,等爬虫结束后统一填充结束时间再写入文件:

import json
from scrapy.item import ItemAdapter

class JsonWriterPipeline:
    def open_spider(self, spider):
        self.item_buffer = []
        self.file = open('ebay_out.jl', 'w', encoding='utf-8')

    def close_spider(self, spider):
        # 爬虫关闭后,给所有暂存的item填充结束时间再写入
        end_time = spider.end_time
        for item in self.item_buffer:
            item['timeClosed'] = end_time
            line = json.dumps(ItemAdapter(item).asdict(), ensure_ascii=False) + "\n"
            self.file.write(line)
        self.file.close()

    def process_item(self, productItem, spider):
        # 先把item放到缓冲区暂存
        self.item_buffer.append(productItem)
        return productItem

场景2:文件末尾追加独立的爬虫结束统计记录(适合大数据量采集,无需暂存)

不需要修改单条商品数据,只需要在所有商品写入完成后,追加一条统计记录即可:

import json
from scrapy.item import ItemAdapter

class JsonWriterPipeline:
    def open_spider(self, spider):
        self.file = open('ebay_out.jl', 'w', encoding='utf-8')
        self.item_count = 0

    def close_spider(self, spider):
        # 追加结束统计记录
        end_info = {
            "record_type": "spider_close_info",
            "end_time": spider.end_time,
            "close_reason": spider.close_reason,
            "total_collected_count": self.item_count
        }
        line = json.dumps(end_info, ensure_ascii=False) + "\n"
        self.file.write(line)
        self.file.close()

    def process_item(self, productItem, spider):
        line = json.dumps(ItemAdapter(productItem).asdict(), ensure_ascii=False) + "\n"
        self.file.write(line)
        self.item_count += 1
        return productItem

三、最后配置生效

在settings.py中开启Pipeline即可:

ITEM_PIPELINES = {
    # 替换为你自己项目中Pipeline的实际路径
    'ebaycomp.pipelines.JsonWriterPipeline': 300,
}

内容的提问来源于stack exchange,提问作者George

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 16:30:05