我有一个json文件,用于存储一些用户信息,包括id
,name
和url
。 json文件如下所示:
{"link": "https://www.example.com/user1", "id": 1, "name": "user1"}
{"link": "https://www.example.com/user1", "id": 2, "name": "user2"}
此文件由scrapy蜘蛛编写。现在我想从json文件中读取urls并抓取每个用户的网页。但我无法从json文件加载数据。
目前,我不知道如何获取这些网址。我想我应该首先阅读json文件中的行。我在Python shell中尝试了以下代码:
import json
f = open('links.jl')
line = json.load(f)
我收到以下错误消息:
Raise ValueError(errmsg("Extra data", s, end, len(s)))
ValueError: Extra data: line 2 column 1- line 138 column 497(char498-67908)
我在网上做了一些搜索。搜索表明json文件可能存在一些格式问题。但是json文件是使用scrapy管道创建并填充项目的。有没有人知道导致错误的原因是什么?以及如何解决?有关阅读网址的任何建议吗?
非常感谢。
答案 0 :(得分:7)
这些是出口商名称暗示的json行。
查看scrapy.contrib.exporter
并查看JsonItemExporter
和JsonLinesItemExporter
这应该可以解决问题:
import json
lines = []
with open('links.jl', 'r') as f:
for line in f:
lines.append(json.loads(line))
答案 1 :(得分:1)
import json
import re
parse_err = re.compile(
r'Extra data: line \d+ column \d+'
r' - line \d+ column \d+'
r' \(char (\d*).*')
def recover_bad_json(data):
while data:
try:
yield json.loads(data)
return
except ValueError, e:
char = parse_err.match(e.args[0]).group(1)
maybe_data, data = data[:int(char)], data[int(char):]
yield json.loads(maybe_data)
CORPUS = r'''{"link": "https://www.domain.com/user1", "id": 1, "name": "user1"}
{"link": "https://www.domain.com/user1", "id": 2, "name": "user2"}
'''
gen_recovered = recover_bad_json(CORPUS)
print gen_recovered.next()
print gen_recovered.next()
print gen_recovered.next()
答案 2 :(得分:0)
如果您怀疑JSON文档可能格式错误,我建议您将文档提交到JSONLint。该工具将美化文档格式,并突出显示解析过程中遇到的任何结构或样式问题。我以前使用过这个工具在JSON文档生成器中找到额外的逗号和破坏的引号。
答案 3 :(得分:0)
之前我发现这种格式设计不合理的JSON API。这可能不是最好的解决方案,但这是一个小函数,我用它来将这种输出转换为包含列表中所有结果对象的字典。
def json_parse(data):
d = data.strip().replace("\n\n", ",")
d = '{"result":[' + d + ']}'
return json.loads(d)
根据分隔它们的换行符的数量,您可能需要稍微修改一下。使用.read()
阅读文件并在数据上调用json_parse
,您应该可以通过访问data["results"]
来迭代所有内容。
如果你可以让你的抓取结果提供有效的JSON,那会更好,但同时这样的事情可以起作用。
答案 4 :(得分:0)
AFAIK,JSON文件应包含单个对象。在你的情况下,你有几个:
{"link": "https://www.domain.com/user1", "id": 1, "name": "user1"}
{"link": "https://www.domain.com/user1", "id": 2, "name": "user2"}
我会做类似的事情:
Python 2.7.3 (default, Sep 26 2012, 21:51:14)
>>> import json
>>> inpt_json = """{"link": "https://www.domain.com/user1", "id": 1, "name": "user1"}
...
... {"link": "https://www.domain.com/user1", "id": 2, "name": "user2"}"""
>>> for line in inpt_json.splitlines():
... line = line.strip()
... if line:
... print json.loads(line)
...
{u'link': u'https://www.domain.com/user1', u'id': 1, u'name': u'user1'}
{u'link': u'https://www.domain.com/user1', u'id': 2, u'name': u'user2'}
>>>
所以,说“我有一个存储一些用户信息的json文件......”是不正确的。 Scrapy将输出存储为“带有json编码行的文件”