【问题标题】:Scraping XML data with BS4 "lxml"使用 BS4 "lxml" 抓取 XML 数据
【发布时间】:2018-09-13 08:00:03
【问题描述】:

试图解决与这个非常相似的问题:

[Scraping XML element attributes with beautifulsoup

我有以下代码:

from bs4 import BeautifulSoup
import requests
r = requests.get('https://www.usda.gov/oce/commodity/wasde/latest.xml')
data = r.text
soup = BeautifulSoup(data, "lxml")
for ce in soup.find_all("Cell"):
    print(ce["cell_value1"])

代码运行没有错误,但不会将任何值打印到终端。

我想为整个页面提取上面提到的“cell_value1”数据,所以我有这样的东西:

2468.58
3061.58
376.64
and so on...

我的 XML 文件的格式与上述问题的解决方案中的示例相同。我确定了特定于我要抓取的属性的适当属性标签。为什么值不打印到终端?

【问题讨论】:

    标签: python python-3.x beautifulsoup lxml elementtree


    【解决方案1】:

    问题是您在 HTML 模式下解析此文件,这意味着标签最终命名为 'cell' 而不是 'Cell'。因此,您可以只使用'cell' 进行搜索,但正确的答案是在 XML 模式下进行解析。

    为此,只需使用'xml' 作为解析器,而不是'lxml'。 ('lxml' 表示“HTML 模式下的lxml”和xml 表示“XML 模式下的lxml”有点不明显,但它是documented。)

    这在Other parser problems中有解释:

    因为HTML tags and attributes are case-insensitive,所有三个 HTML 解析器都将标记和属性名称转换为小写。也就是说,标记<TAG></TAG> 被转换为<tag></tag>。如果你想保留大小写混合或大写的标签和属性,你需要parse the document as XML


    由于第二个问题,您的代码仍然失败:一些 Cell 节点是空的,并且没有要打印的 cell_value1 属性,但您正试图无条件地打印它。

    所以,你想要的是这样的:

    soup = BeautifulSoup(data, "xml")
    for ce in soup.find_all("Cell"):
        try:
            print(ce["cell_value1"])
        except KeyError:
            pass
    

    【讨论】:

    • 您可以使用 'cell_value1' 作为关键字参数并使您的代码更短一些,例如soup.find_all("Cell", cell_value1=True)。但这不是问题,+1
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-03-20
    • 1970-01-01
    • 1970-01-01
    • 2020-10-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多