scrapy官方文档的去重模块,只能实现对当前抓取数据的去重,下面是官方 API
- from scrapy.exceptions import DropItem
- class DuplicatesPipeline(object):
- def __init__(self):
- self.ids_seen = set()
- def process_item(self, item, spider):
- if item['id'] in self.ids_seen:
- raise DropItem("Duplicate item found: %s" % item)
- else:
- self.ids_seen.add(item['id']) ##这里换成你自己的item["#"]
- return item
当有一天需求变了,在你像mysql 数据库保存的时候,发现已经有一部分已经存在,有一部分新的数据,你又需要添加到mysql数据库中,这时候你就需要通过redis来作为中间件,通过url来确保爬过的数据不会再爬,做到增量爬取,
- from redis import Redis
- import pandas as pd
- import pymysql
- redis_db = Redis(host='your_setting', port=6379, db=4) #连接redis
- redis_data_dict = "k_url"
- class FirstScrapyPipeline(object):
- def __init__(self):
- self.connect = pymysql.connect(host='your_seting', port=3306, user=user,password='yourseting',database='yourpassword,'db='dbname',charset=vacher)
- self.cursor = self.connect.cursor()##这里我是先将数据存到mysql数据库,建立游标
- redis_db.flushdb()## 删除redis里面的key
- if redis_db.hlen(redis_data_dict) == 0:
- sql = "SELECT url FROM ts_dobn;
- df = pd.read_sql(sql, self.connect)# 读MySQL数据
- for url in df['url'].get_values(): # 把每一条的值写入key的字段里
- redis_db.hset(redis_data_dict, url, 0)
- def process_item(self, item, spider):
- if redis_db .hexists (redis_data_dict, item['url']): # 取item里的url和key里的字段对比,看是否存在,存在就丢掉这个item。不存在返回item给后面的函数处理
- raise DropItem("Duplicate item found: %s" % item)
- values = [item["title"],item['start'],item['desc'],item['url']]
- self.do_insert(values)
- self.connect.commit()
- return item
- def do_insert(self,values):
- sql = 'insert into ts_douban VALUES (0,%s,%s,%s,%s)'
- self.cursor.execute(sql,values)
- def close_spider(self,spider):
- self.connect.close()