使用 BS4 "lxml" 抓取 XML 数据

gab*_*abe 2 python lxml beautifulsoup elementtree python-3.x

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

[用beautifulsoup抓取XML元素属性

我有以下代码:

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"])
Run Code Online (Sandbox Code Playgroud)

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

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

2468.58
3061.58
376.64
and so on...
Run Code Online (Sandbox Code Playgroud)

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

aba*_*ert 7

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

为此,只需将其'xml'用作解析器而不是'lxml'. (有点不明显,这'lxml'意味着“lxml在 HTML 模式下”和xmllxml在 XML 模式下”,但它被记录在案。)

这在其他解析器问题中有解释:

因为HTML 标记和属性不区分大小写,所以所有三个 HTML 解析器都将标记和属性名称转换为小写。也就是说,标记<TAG></TAG>被转换为<tag></tag>. 如果要保留大小写混合或大写的标记和属性,则需要将文档解析为 XML


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

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

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

  • 您可以使用 'cell_value1' 作为关键字参数并使您的代码更短一些,例如`soup.find_all("Cell", cell_value1=True)`。但这不是问题,+1 (2认同)