【问题标题】:Dropping duplicate items from Scrapy pipeline从 Scrapy 管道中删除重复项
【发布时间】:2020-11-25 07:13:52
【问题描述】:

我的scrapy爬虫从ptt网站收集数据,并使用gspread将爬取的数据输入谷歌电子表格。我的ptt蜘蛛每天都会解析ptt网站上最新的40篇文章,现在我想在这个最新的40篇文章中删除重复数据,例如,如果post_title或post_link与昨天相同,则不需要解析这个发布到谷歌电子表格中。
我知道我应该在 Scarpy 中使用 DropItem,但实际上我不知道如何修复我的代码(我是 Python 的新手),并且想为此寻求帮助,谢谢。

这是我的ppt蜘蛛代码

    # -*- coding: utf-8 -*-
    import scrapy
    # from scrapy.exceptions import CloseSpider
    from myFirstScrapyProject.items import MyfirstscrapyprojectItem
    
    class PttSpider(scrapy.Spider):
        count_page = 1
        name = 'ptt'
        allowed_domains = ['www.ptt.cc/']
        start_urls = ['https://www.ptt.cc/bbs/e-shopping/search?q=%E8%9D%A6%E7%9A%AE']+['https://www.ptt.cc/bbs/e-seller/search?q=%E8%9D%A6%E7%9A%AE']
        # start_urls = ['https://www.ptt.cc/bbs/e-shopping/index.html']
    
        def parse(self, response):
            items = MyfirstscrapyprojectItem()
            for q in response.css('div.r-ent'):
                items['push']=q.css('div.nrec > span.h1::text').extract_first()
                items['title']=q.css('div.title > a::text').extract_first()
                items['href']=q.css('div.title> a::attr(href)').extract_first()
                items['date']=q.css('div.meta > div.date ::text').extract_first()
                items['author']=q.css('div.meta > div.author ::text').extract_first()
                yield(items)

这是我的管道

from myFirstScrapyProject.exporters import GoogleSheetItemExporter
from scrapy.exceptions import DropItem

class MyfirstscrapyprojectPipeline(object):
    def open_spider(self, spider):
        self.exporter = GoogleSheetItemExporter()
        self.exporter.start_exporting()

    def close_spider(self, spider):
        self.exporter.finish_exporting()

    def process_item(self, item, spider):
        self.exporter.export_item(item)
        return item

感谢sharmiko,我重写了它,但它似乎不起作用,我应该修复什么?

from myFirstScrapyProject.exporters import GoogleSheetItemExporter
from scrapy.exceptions import DropItem

class MyfirstscrapyprojectPipeline(object):

    def open_spider(self, spider):
        self.exporter = GoogleSheetItemExporter()
        self.exporter.start_exporting()

    def close_spider(self, spider):
        self.exporter.finish_exporting()

#    def process_item(self, item, spider):
#        self.exporter.export_item(item)
#        return item

#class DuplicatesTitlePipeline(object):
    def __init__(self):
        self.article = set()
    def process_item(self, item, spider):
        href = item['href'] 
        if href in self.article:
            raise DropItem('duplicates href found %s', item)
        self.exporter.export_item(item)
        return(item)

这是导出到谷歌表格的代码

import gspread
from oauth2client.service_account import ServiceAccountCredentials
from scrapy.exporters import BaseItemExporter

class GoogleSheetItemExporter(BaseItemExporter):
    def __init__(self):
        scope = ['https://spreadsheets.google.com/feeds','https://www.googleapis.com/auth/drive']
        credentials = ServiceAccountCredentials.from_json_keyfile_name('pythonupload.json', scope)
        gc = gspread.authorize(credentials)
        self.spreadsheet = gc.open('Community')
        self.worksheet = self.spreadsheet.get_worksheet(1)

    def export_item(self, item):
        self.worksheet.append_row([item['push'], item['title'], 
        item['href'],item['date'],item['author']])

【问题讨论】:

  • 您是否也在您的代码中评论了#class DuplicatesTitlePipeline(object): 这一行?还是直接在 stackoverflow 上输入?
  • 也不要忘记在每次添加新管道时更新 ITEM_PIPELINES 列表中的 settings.py
  • 当然,我添加了#class DuplicatesTitlePipeline(object):来尝试运行,并在settings.py中添加了这个管道,但它似乎不起作用,所以我只是给它一个#来忽略代码。
  • 如果错误回溯不包含任何敏感信息,能否粘贴?
  • 您是否运行了代码并添加了重复的元素?或者这是之前收集的列表。

标签: python scrapy web-crawler


【解决方案1】:

您应该修改您的process_item 函数以检查重复元素,如果找到,您可以直接删除它。

from scrapy.exceptions import DropItem
...
def process_item(self, item, spider):
    if [ your duplicate check logic goes here]:
       raise DropItem('Duplicate element found')
    else:
       self.exporter.export_item(item)
       return item

丢弃的项目不再传递给其他管道组件。您可以阅读有关管道的更多信息here

【讨论】:

  • 我还写了一个exporter.py来描述如何连接google sheet api,并将数据输入到google sheet中。我还应该修复exporter.py 中的代码吗?因为我重写了 process_item 函数,但它似乎不起作用。
  • 你能分享谷歌表格代码并粘贴完整的错误信息吗?
  • 嗨!我在帖子里加了代码,请看帖子~谢谢
猜你喜欢
  • 1970-01-01
  • 2015-11-24
  • 1970-01-01
  • 2014-12-27
  • 1970-01-01
  • 2017-08-12
  • 1970-01-01
  • 1970-01-01
  • 2019-08-04
相关资源
最近更新 更多