从 beautifulsoup 切换到 htmlelement - 如何查找元素
Switching from beautifulsoup to htmlelement - how to find elements
我有一个现有的过程,可以从使用 xbrli xml 标准的 html 文档中提取元素。
可以找到文档示例here:
该过程运行良好(我正在使用多处理并行工作)但我有 ~20m html 和 xml 文件要处理,我发现 beautifulsoup 是核心瓶颈。
我正在寻找 htmlelement 作为提取我需要的数据的一种希望更快的替代方法,但我正在努力寻找元素。例如,在 BS 中我可以执行以下操作:
for tag in soup.find_all('xbrli:unit'):
l_unitid = tag.attrs.get('id')
l_value = tag.text
l_unit_dict[l_unitid] = {'unitid':l_unitid,'value':l_value}
它会找到所有 xbrli:unit 标签,我可以轻松提取它们的值。
但是,当我在 html 元素中尝试类似的操作时,出现以下异常:
import htmlement
source = htmlement.parse("Prod223_2542_00010416_20190331.html")
for tag in source.iterfind('.//xbrli:unit'):
l_unitid = tag.attrs.get('id')
l_value = tag.text
print(l_unitid)
print(l_value)
SyntaxError: prefix 'xbrli' not found in prefix map
谷歌搜索让我找到了几篇文章,但我似乎无法取得进展
Parsing XML with namespace in Python via 'ElementTree'
我已经尝试添加命名空间映射,但它就是找不到任何东西,无论我把东西放在哪个方向,或者我寻找什么标签
source = htmlement.parse("Prod223_2542_00010416_20190331.html")
namespaces = {'xbrli': 'period'}
for tag in source.iterfind('.//xbrli:period',namespaces):
l_unitid = tag.attrs.get('id')
l_value = tag.text
namespaces = {'xbrli': 'period'}
for tag in source.iterfind('.//{xbrli}period',namespaces):
l_unitid = tag.attrs.get('id')
l_value = tag.text
print(l_unitid)
print(l_value)
namespaces = {'period':'xbrli'}
for tag in source.iterfind('.//{xbrli}period',namespaces):
l_unitid = tag.attrs.get('id')
l_value = tag.text
print(l_unitid)
print(l_value)
namespaces = {'period':'xbrli'}
for tag in source.iterfind('.//period',namespaces):
l_unitid = tag.attrs.get('id')
l_value = tag.text
print(l_unitid)
print(l_value)
全部 return 没有 - 他们没有进入循环。我对如何使用 elementree 结构与 BS 的理解显然有一些非常错误的地方,但我不太清楚如何从一个转移到另一个。
欢迎提出任何建议。
在我得到建议的答案之前有两条一般性评论:
首先,您正在处理 xml 文档,因此通常最好使用 xml,而不是 html 解析器。这就是我在下面使用的,而不是 beautifull soup 或 htmlelement.
其次,关于 xbrl 的总体情况:从痛苦的经历(以及许多其他人指出的那样)来看,xbrl 很糟糕。它表面上闪闪发亮,但一旦打开引擎盖,它就会变得一团糟。所以我不羡慕你...
并且,话虽如此,我已尝试大致了解您可能正在寻找的内容。我没有费心去创建字典或列表,只是使用了 print()
语句。显然,如果对你有帮助,你可以修改成你自己的要求:
from lxml import etree
import requests
r = requests.get('https://beta.companieshouse.gov.uk/company/00010416/filing-history/MzI1MTU3MzQzMmFkaXF6a2N4/document?format=xhtml&download=1')
root = etree.fromstring(r.content)
units = root.xpath(".//*[local-name()='unit'][@id]/@id")
for unit in units:
unit_id = unit
print('unit: ', unit)
print('----------------------------')
context = root.xpath(".//*[local-name()='context']")
for tag in context:
id = tag.xpath('./@id')
print('ID: ',id)
info = tag.xpath('./*[local-name()="entity"]')
identifier = info[0].xpath('.//*[local-name()="identifier"]')[0].text
print('identifier: ',identifier)
member = info[0].xpath('.//*[local-name()="explicitMember"]')
if len(member)>0:
dimension = member[0].attrib['dimension']
explicitMember = member[0].text
print('dimension: ',dimension,' explicit member: ',explicitMember)
periods = tag.xpath('.//*[local-name()="period"]')
for period in periods:
for child in period.getchildren():
if 'instant' in child.tag:
instant = child.text
print('instant: ',instant)
else:
dates = period.xpath('.//*')
start_date = dates[0].text
end_date = dates[1].text
print('start date: ', start_date,' end date: ',end_date)
print('===================')
输出的随机样本:
ID: ['cfwd_31_03_2018']
identifier: 00010416
instant: 2018-03-31
start date: 2017-04-01 end date: 2018-03-31
===================
ID: ['CountriesHypercube_FY_31_03_2019_Set1']
identifier: 00010416
dimension: ns15:CountriesRegionsDimension explicit member: ns15:EnglandWales
instant: 2018-03-31
start date: 2018-04-01 end date: 2019-03-31
我有一个现有的过程,可以从使用 xbrli xml 标准的 html 文档中提取元素。
可以找到文档示例here:
该过程运行良好(我正在使用多处理并行工作)但我有 ~20m html 和 xml 文件要处理,我发现 beautifulsoup 是核心瓶颈。
我正在寻找 htmlelement 作为提取我需要的数据的一种希望更快的替代方法,但我正在努力寻找元素。例如,在 BS 中我可以执行以下操作:
for tag in soup.find_all('xbrli:unit'):
l_unitid = tag.attrs.get('id')
l_value = tag.text
l_unit_dict[l_unitid] = {'unitid':l_unitid,'value':l_value}
它会找到所有 xbrli:unit 标签,我可以轻松提取它们的值。
但是,当我在 html 元素中尝试类似的操作时,出现以下异常:
import htmlement
source = htmlement.parse("Prod223_2542_00010416_20190331.html")
for tag in source.iterfind('.//xbrli:unit'):
l_unitid = tag.attrs.get('id')
l_value = tag.text
print(l_unitid)
print(l_value)
SyntaxError: prefix 'xbrli' not found in prefix map
谷歌搜索让我找到了几篇文章,但我似乎无法取得进展
Parsing XML with namespace in Python via 'ElementTree'
我已经尝试添加命名空间映射,但它就是找不到任何东西,无论我把东西放在哪个方向,或者我寻找什么标签
source = htmlement.parse("Prod223_2542_00010416_20190331.html")
namespaces = {'xbrli': 'period'}
for tag in source.iterfind('.//xbrli:period',namespaces):
l_unitid = tag.attrs.get('id')
l_value = tag.text
namespaces = {'xbrli': 'period'}
for tag in source.iterfind('.//{xbrli}period',namespaces):
l_unitid = tag.attrs.get('id')
l_value = tag.text
print(l_unitid)
print(l_value)
namespaces = {'period':'xbrli'}
for tag in source.iterfind('.//{xbrli}period',namespaces):
l_unitid = tag.attrs.get('id')
l_value = tag.text
print(l_unitid)
print(l_value)
namespaces = {'period':'xbrli'}
for tag in source.iterfind('.//period',namespaces):
l_unitid = tag.attrs.get('id')
l_value = tag.text
print(l_unitid)
print(l_value)
全部 return 没有 - 他们没有进入循环。我对如何使用 elementree 结构与 BS 的理解显然有一些非常错误的地方,但我不太清楚如何从一个转移到另一个。
欢迎提出任何建议。
在我得到建议的答案之前有两条一般性评论: 首先,您正在处理 xml 文档,因此通常最好使用 xml,而不是 html 解析器。这就是我在下面使用的,而不是 beautifull soup 或 htmlelement.
其次,关于 xbrl 的总体情况:从痛苦的经历(以及许多其他人指出的那样)来看,xbrl 很糟糕。它表面上闪闪发亮,但一旦打开引擎盖,它就会变得一团糟。所以我不羡慕你...
并且,话虽如此,我已尝试大致了解您可能正在寻找的内容。我没有费心去创建字典或列表,只是使用了 print()
语句。显然,如果对你有帮助,你可以修改成你自己的要求:
from lxml import etree
import requests
r = requests.get('https://beta.companieshouse.gov.uk/company/00010416/filing-history/MzI1MTU3MzQzMmFkaXF6a2N4/document?format=xhtml&download=1')
root = etree.fromstring(r.content)
units = root.xpath(".//*[local-name()='unit'][@id]/@id")
for unit in units:
unit_id = unit
print('unit: ', unit)
print('----------------------------')
context = root.xpath(".//*[local-name()='context']")
for tag in context:
id = tag.xpath('./@id')
print('ID: ',id)
info = tag.xpath('./*[local-name()="entity"]')
identifier = info[0].xpath('.//*[local-name()="identifier"]')[0].text
print('identifier: ',identifier)
member = info[0].xpath('.//*[local-name()="explicitMember"]')
if len(member)>0:
dimension = member[0].attrib['dimension']
explicitMember = member[0].text
print('dimension: ',dimension,' explicit member: ',explicitMember)
periods = tag.xpath('.//*[local-name()="period"]')
for period in periods:
for child in period.getchildren():
if 'instant' in child.tag:
instant = child.text
print('instant: ',instant)
else:
dates = period.xpath('.//*')
start_date = dates[0].text
end_date = dates[1].text
print('start date: ', start_date,' end date: ',end_date)
print('===================')
输出的随机样本:
ID: ['cfwd_31_03_2018']
identifier: 00010416
instant: 2018-03-31
start date: 2017-04-01 end date: 2018-03-31
===================
ID: ['CountriesHypercube_FY_31_03_2019_Set1']
identifier: 00010416
dimension: ns15:CountriesRegionsDimension explicit member: ns15:EnglandWales
instant: 2018-03-31
start date: 2018-04-01 end date: 2019-03-31