我是一个Python初学者,希望我的问题不要太长,请告诉我以后的问题是否应该更简洁,谢谢!
我正在打开一个. xhtml文件,其中包含作为XML (iXBRL标准)的财务数据。现在我正在用BeautifulSoup4 ("html.parser")解析文件。
url = r"tk2021.xhtml"
data = open(url, encoding="utf8")
soup = BeautifulSoup(data, "html.parser")
然后我创建不同的列表,其中包含所有匹配的标签。我稍后将使用这些列表来迭代并从每个标记中提取所有相关数据并将其加载到pd中。DataFrame
ix_nonfraction = soup.find_all({"ix:nonfraction"})
xbrli_unit = soup.find_all({"xbrli:unit"})
按预期工作。我纠结的是下一步该怎么办。
我试图创建包含所有<xbrli:context>
标签的另一个列表。它们有<xbrli:entity>
子标签,我需要在创建列表之前将其删除。我是这样做的:
for tag in soup("xbrli:entity"):
tag.decompose()
xbrli_context = soup.find_all({"xbrli:context"})
这也工作得很好,但我不能访问原来的soup
稍后在我的脚本(所有的<xbrli:entity>
标签都缺失)。另外,我在BS4文档中读到,分解标签或NavigableString的行为没有定义,您不应该将其用于任何"。所以我认为为这个操作创建一个新的soup2
会更简洁,所以原来的soup
可以在以后使用。
这里我不明白发生了什么:当我用不同的名字soup2 = BeautifulSoup(data, "html.parser")
创建第二个汤并使用print(soup2.prettify())
时,它没有打印任何东西。对soup
做同样的工作就可以了。
为什么soup2
看起来是空的?我如何处理一种汤的多个版本,以便我总是可以从最初的汤开始,如果我想?
我不建议阅读XML或XHTML级别的内联XBRL文件。相反,强烈建议使用XBRL处理器,它将在适当的抽象级别上提供XBRL语义。
XBRL数据模型基于数据集,通过直接将数据作为XML读取,您实际上是从头开始重新构建XBRL处理器。
例如,有一个名为Arelle的开源处理器,在Python中可用:
https://pypi.org/project/arelle/
主项目页面:https://arelle.org/arelle/
正如在评论中已经提到的,由于data
是文件对象,在BeautifulSoup
第一次读取之后,需要在再次读取之前重新打开它。如果使用
with open(url, encoding="utf8") as f:
data = f.read()
因为.read()
返回一个字符串,所以data
将只是一个字符串。
你也可以完全去掉data
而使用
# soup = BeautifulSoup(open(url, encoding="utf8"), "html.parser") ## less safe
with open(url, encoding="utf8") as f: soup = BeautifulSoup(f, "html.parser")
Btw,最好使用with open
,因为裸open
之后应该是.close
[但如果你像在注释行中那样做,你就不能这样做了]。