用Python抓取格式奇怪的JSON页面

1 投票
2 回答
1215 浏览
提问于 2025-04-18 14:40

我正在抓取一个网页的数据,网页的格式是这样的:

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

问题是,页面上有其他内容,JSON数据被放在引号里,并且在一个'pre'标签里面,里面还有其他的HTML标签,像这样:

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

有没有办法绕过这种糟糕的格式,直接从一个包含JSON对象列表的字符串中提取出JSON对象,最好在这个过程中去掉那些嵌套的标签?

编辑:我现在已经安装并开始学习BeautifulSoup4,正如Mauricio推荐的那样,但我还是有点困难。使用.pre操作符在'soup'上给我的结果是:

<pre> [{ ... (格式良好的JSON,但仍然在标签里面) ...}]</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

我建议你使用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标签及其下面每个标签里的文本。

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'}]

撰写回答