账号密码登录
微信安全登录
微信扫描二维码登录

登录后绑定QQ、微信即可实现信息互通

手机验证码登录
找回密码返回
邮箱找回 手机找回
注册账号返回
其他登录方式
分享
  • 收藏
    X
    Scrapy 异步写入mysql时部分数据重复问题
    41
    0

    scrapy爬取百度新闻,参考网上回答修改Pipeline部分代码:

    def process_item(self,item,spider):
        asynItem = copy.deepcopy(item)
        query=self.dbpool.runInteraction(self.do_insert,asynItem)
        query.addErrback(self.handle_error)
    
    def handle_error(self,failure):
        print(failure)
    
    def do_insert(self,cursor,item):
        check_sql = "select count(*) from `company_news_scrapy` where (`link`,`company_name`) =({},{})".format("'" + item['link'] + "'","'" + item['company_name'] + "'")
        cursor.execute(check_sql)
        rest = cursor.fetchall()
        if rest[0]['count(*)']==0:
            insert_sql = "insert into `company_news_scrapy`(`company_name`,`link`) values(%s,%s);"
            cursor.execute(insert_sql, (item['company_name'],item['link']))
            

    仍然出现部分数据重复插入问题,求帮助。

    0
    打赏
    收藏
    点击回答
        全部回答
    • 0
    • cut77 普通会员 1楼

      在Scrapy中,使用异步方式将数据写入MySQL时出现部分数据重复的问题,主要原因可能有以下几点:

      1. 并发控制问题:由于Scrapy的爬虫是异步非阻塞的,当多个请求同时返回并尝试写入数据库时,如果没有采取适当的并发控制措施(如加锁、队列等),可能会导致同一份数据被多次写入。

      2. Item Pipeline处理不当:在Scrapy的Item Pipeline中,需要确保每个item只被处理一次。例如,在process_item方法中,如果直接调用数据库插入操作而没有进行去重判断或其他同步控制,就可能出现重复。

      3. Duplicates Filter未启用或配置不正确:Scrapy提供了一个内置的去重过滤器,可以通过设置DUPEFILTER_CLASS来启用,并根据需求选择合适的去重策略。如果这个去重过滤器未启用或者配置不正确,可能导致重复抓取和存储相同的数据。

      4. MySQL事务问题:在高并发场景下,MySQL事务的隔离级别也可能影响到数据的一致性,若设置不当可能会出现幻读等问题,进而导致数据重复。

      解决办法:

      • 对于并发控制,可以考虑使用中间件或者其他同步机制保证每次只有一个请求执行写库操作。

      • 在Item Pipeline中增加一个唯一标识字段(如url、ID等)做去重判断,确保数据不会重复插入。

      • 正确配置Scrapy的Duplicates Filter,避免重复抓取。

      • 调整MySQL的事务隔离级别,或者在应用层面对插入操作进行适当的控制以防止并发冲突。

      • 使用消息队列(如RabbitMQ、Kafka等)作为缓冲,先将数据发送到队列,再由另一端服务消费并入库,这样可以分散写库压力并利用队列的特性天然实现去重。

    更多回答
    扫一扫访问手机版
    • 回到顶部
    • 回到顶部