使用BS4" lxml"刮取XML数据

时间:2018-04-03 21:33:29

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

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

[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文件的格式与上述问题的解决方案中的示例相同。我确定了特定属性标签,特定于我想要刮去的属性。为什么值不打印到终端?

1 个答案:

答案 0 :(得分:4)

问题是你是在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