【问题标题】:Why BeautifulSoup add <html><body><p> to my results?为什么 BeautifulSoup 将 <html><body><p> 添加到我的结果中?
【发布时间】:2018-07-08 14:26:52
【问题描述】:

问题

我有以下Page01.htm

<!DOCTYPE html><html lang="it-IT"><head>    <meta charset="utf-8">    <meta http-equiv="X-UA-Compatible" content="IE=Edge">    <head><title>Title here</title></head>
<body>
<script id="TargetID" type="application/json"><![CDATA[
{ "name":"Kate", "age":22, "city":"Boston"}
]]>
</script><script id=“AnotherID” type="application/json"><![CDATA[{ "name":"John", "age":31, "city":"New York"}]]>
</script>
</body></html>

我想用ID=TargetID 提取脚本标签之间的JSON 中的信息。

我做了什么

我编写了以下 Python 3.6 代码:

from bs4 import BeautifulSoup
import codecs

page_path="/Users/me/Page01.htm"

page = codecs.open(page_path, "r", "utf-8")

soup = BeautifulSoup(page.read(), "lxml")
vegas = soup.find_all(id="TargetID")

invalid_tags = ['script']
soup = BeautifulSoup(str(vegas),"lxml")
for tag in invalid_tags: 
    for match in soup.findAll(tag):
        match.replaceWithChildren()

JsonZ = str(soup)

现在,如果我查看 vegas 变量内部,我可以看到

[<script id="TargetID" type="application/json"><![CDATA[ {
> "name":"Kate", "age":22, "city":"Boston"} ]]> </script>]

但如果我尝试删除脚本标签(使用this answer 脚本),我会得到以下JsonZ 变量

'<html><body><p>[&lt;![CDATA[\n{ "name":"Kate", "age":22, "city":"Boston"}\n]]&gt;\n]</p></body></html>'

没有脚本标签但有另外 3 个标签 (&lt;html&gt;&lt;body&gt;&lt;p&gt;) 完全没用。 我的目标是让以下字符串 { "name":"Kate", "age":22, "city":"Boston"} 与 Python JSON 模块一起加载。

【问题讨论】:

    标签: python json python-3.x beautifulsoup cdata


    【解决方案1】:

    它可以变得更简单:

    from bs4 import BeautifulSoup
    soup = BeautifulSoup(open("/Users/me/Page01.htm", encoding='utf-8'), "html.parser")
    result = soup.find('script', type='application/json', id='TargetID').text
    # Workaround to get CDATA content (It seems that it can't be done with bs):
    result = result.replace("<![CDATA[", "").replace("]]>", "").strip()
    

    【讨论】:

    • 谢谢,它工作得很好,它是一个非常好的代码!我将@Bill Bell 的答案标记为“acceprance”,只是因为对 BeautifulSoup 为什么添加上面列出的三个标签进行了解释。再次感谢您。
    【解决方案2】:

    BeautifulSoup 几乎可以接受任何给它的东西,并尝试将其转换为完整的 HTML 页面。这就是您收到'&lt;html&gt;&lt;body&gt; ...' 的原因。通常这是一件好事,因为 HTML 的格式可能很糟糕,但 BeautifulSoup 仍会处理它。

    在您的情况下,提取该 json 的一种方法是这样的。

    >>> import bs4
    >>> page = bs4.BeautifulSoup(open('Page01.htm').read(), 'lxml')
    >>> first_script = page.select('#TargetID')[0].text
    >>> first_script 
    '<![CDATA[\n{ "name":"Kate", "age":22, "city":"Boston"}\n]]>\n'
    >>> content = first_script[first_script.find('{'): 1+first_script.rfind('}')]
    >>> content
    '{ "name":"Kate", "age":22, "city":"Boston"}'
    

    一旦你有了这个,你就可以把它变成一个 Python 字典,就像这样。

    >>> import json
    >>> d = json.loads(content)
    >>> d['name']
    'Kate'
    >>> d['age']
    22
    >>> d['city']
    'Boston'
    

    【讨论】:

      猜你喜欢
      • 2017-08-25
      • 2022-11-16
      • 1970-01-01
      • 1970-01-01
      • 2013-09-20
      • 1970-01-01
      • 2011-03-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多