我在python中使用了crawler框架“scrapy”,我使用pipelines.py文件将我的项目以json格式存储到文件中。执行此操作的代码如下所示 导入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
.
请建议一种方法来执行此操作。
注意:请注意我必须以“追加”模式打开文件,因为我可能会抓取一组不同的链接,但使用相同的start_url运行爬虫两次应该将相同的数据写入文件两次
答案 0 :(得分:1)
您可以使用一些自定义中间件(例如this)过滤掉重复项。但是,要在你的蜘蛛中实际使用它,你需要另外两件事:某些方法可以将id分配给项目,以便过滤器可以识别重复项,以及某些方法可以在蜘蛛运行之间保持访问ID的集合。第二个很简单 - 你可以使用像搁置一样的pythonic,或者你可以使用这些天流行的众多键值商店之一。但是,第一部分将变得更难,并且将取决于您试图解决的问题。