爬虫运行两次时产生重复数据?
我在Python中使用一个叫“scrapy”的爬虫框架,并且我用pipelines.py文件把抓取到的内容存储为json格式的文件。下面是实现这个功能的代码:
class AYpiPipeline(object):
def __init__(self):
self.file = open("a11ypi_dict.json","ab+")
# this method is called to process an item after it has been scraped.
def process_item(self, item, spider):
d = {}
i = 0
# Here we are iterating over the scraped items and creating a dictionary of dictionaries.
try:
while i<len(item["foruri"]):
d.setdefault(item["foruri"][i],{}).setdefault(item["rec"][i],{})[item["foruri_id"][i]] = item['thisurl'] + ":" + item["thisid"][i]
i+=1
except IndexError:
print "Index out of range"
# Writing it to a file
json.dump(d,self.file)
return item
问题是,当我运行爬虫两次(比如说)时,我的文件里会出现重复的抓取内容。我尝试通过先读取文件,然后把读取到的数据和新数据进行比较来避免这个问题,但从文件中读取的数据是json格式的,所以我用json.loads()函数来解码,但这样并没有成功:
import json
class AYpiPipeline(object):
def __init__(self):
self.file = open("a11ypi_dict.json","ab+")
self.temp = json.loads(file.read())
# this method is called to process an item after it has been scraped.
def process_item(self, item, spider):
d = {}
i = 0
# Here we are iterating over the scraped items and creating a dictionary of dictionaries.
try:
while i<len(item["foruri"]):
d.setdefault(item["foruri"][i],{}).setdefault(item["rec"][i],{})[item["foruri_id"][i]] = item['thisurl'] + ":" + item["thisid"][i]
i+=1
except IndexError:
print "Index out of range"
# Writing it to a file
if d!=self.temp: #check whether the newly generated data doesn't match the one already in the file
json.dump(d,self.file)
return item
.
请给我建议一个解决方法。
注意:我必须以“追加”模式打开文件,因为我可能会抓取不同的链接,但如果两次运行爬虫使用相同的起始网址,那么应该把相同的数据写入文件两次。
1 个回答
1
你可以通过一些自定义的中间件来过滤掉重复的数据,比如这个。不过,要在你的爬虫中真正使用这个,你还需要两个东西:一种给项目分配ID的方法,这样过滤器才能识别重复项,以及一种在爬虫运行之间保存已访问ID集合的方法。第二个比较简单——你可以用一些Python中常用的工具,比如shelve,或者使用现在流行的许多键值存储。第一部分会比较难,具体要看你想解决的问题是什么。