在python中使用格式不正确的JSON刮取页面

时间:2014-07-24 22:17:40

标签: python html json html-parsing beautifulsoup

我正在抓取网页上的数据,其格式如下:

<!-- Web header up here -->
[{"foo": "Bar", "foo2": "Bar2"},
 {"foo3": ["hello", "world"], "foo4": "Bar4"},
...
]
<!-- Web footer here -->

问题是JSON出现在包含其他内容的页面上,并且页面源在引号内有JSON列表,在'pre'标记内,其中包含JSON中的其他html标记,如下所示:

<pre>" [{ "foo": "Bar", <p>"foo2": "Bar2"</p>}, ... ] "</pre>

有没有办法绕过这个糟糕的格式并获得一个JSON对象列表,给出一个JSON对象列表,最好是在过程中删除嵌入式标签?

编辑:我现在已经安装并开始按照Mauricio的建议学习BeautifulSoup4,但我仍然会略显短暂。在'汤'上使用.pre操作符给我

<pre> [{ ... (Good formatted JSON but inside tags still) ...}]</pre>

HTML:<pre>代码上方和下方只有一些标题。)

<pre>
[{
  "title": “blah”,
  "refs": [“a”, “a”],
  "description": [“a”,
  “a”,
  "a”],
  “a”: [
    {“a”: “a"}]
},
{
  "title": “a”,
  "refs": [“a”, “a”],
  "description": [“a”,
  “a”,
  “a”],
  “a”: [
    {“a”: “a”}]
}]
</pre>

2 个答案:

答案 0 :(得分:2)

您需要获取.textstrip()引号和空格。

然后,您可以使用json.loads()加载json字符串:

import json
from bs4 import BeautifulSoup


data = """
<div>
    <pre>" [{ "foo": "Bar", <p>"foo2": "Bar2"</p>}] "</pre>
</div>
"""

soup = BeautifulSoup(data)

json_data = soup.pre.text.strip('" ')
print json.loads(json_data)

打印:

[{u'foo': u'Bar', u'foo2': u'Bar2'}]

还有另一个问题 - pre内的引号不正常,您应该替换它们:

# -*- coding: utf-8 -*-

import json
from bs4 import BeautifulSoup


data = u"""
<div>
    <pre>
[{
  "title": “blah”,
  "refs": [“a”, “a”],
  "description": [“a”,
  “a”,
  "a”],
  “a”: [
    {“a”: “a"}]
},
{
  "title": “a”,
  "refs": [“a”, “a”],
  "description": [“a”,
  “a”,
  “a”],
  “a”: [
    {“a”: “a”}]
}]
</pre>
</div>
"""

soup = BeautifulSoup(data)

json_data = soup.pre.text.encode('utf-8').strip('" ').replace('“', '"').replace('”', '"')
print json.loads(json_data)

打印:

[{u'a': [{u'a': u'a'}], u'refs': [u'a', u'a'], u'description': [u'a', u'a', u'a'], u'title': u'blah'}, 
 {u'a': [{u'a': u'a'}], u'refs': [u'a', u'a'], u'description': [u'a', u'a', u'a'], u'title': u'a'}]

答案 1 :(得分:0)

我建议您使用BeautifulSoup来解析网页。

http://www.crummy.com/software/BeautifulSoup/

文档:

http://www.crummy.com/software/BeautifulSoup/bs4/doc/

然后你可以做类似的事情:

from bs4 import BeautifulSoup
from urllib2 import urlopen

html_doc = urlopen("http://www.google.com/").read()
soup = BeautifulSoup(html_doc)
print soup.p.text

它将从P下面的每个标签中提取文本,包括P本身。