【问题标题】:using bs4 to find a html tag (h2) having text使用 bs4 查找具有文本的 html 标签 (h2)
【发布时间】:2016-05-29 15:08:52
【问题描述】:

对于这部分html代码:

html3= """<a name="definition"> </a>
<h2><span class="sectioncount">3.342.2323</span> Content Logical Definition <a title="link to here" class="self-link" href="valueset-investigation"><img src="ta.png"/></a></h2>
<hr/>
<div><p from the following </p><ul><li>Include these codes as defined in http://snomed.info/sct<table><tr><td><b>Code</b></td><td><b>Display</b></td></tr><tr><td>34353553</td><td>Examination / signs</td><td/></tr><tr><td>35453453453</td><td>History/symptoms</td><td/></tr></table></li></ul></div>
<p> </p>"""

我将使用 beautifulsoup 来查找其文本等于“内容逻辑定义”的 h2 和下一个兄弟。但是beautifulsoup 找不到h2。以下是我的代码:

soup = BeautifulSoup(html3, "lxml")
f= soup.find("h2", text = "Content Logical Definition").nextsibilings

这是一个错误:

AttributeError: 'NoneType' object has no attribute 'nextsibilings'

文本中有几个“h2”,但唯一使这个 h2 独一无二的字符是“内容逻辑定义”。找到这个h2之后,我要从表中提取数据并在它下面列出。

【问题讨论】:

  • 试试nextsiblings???

标签: python html beautifulsoup html-parsing bs4


【解决方案1】:

主要问题是您定位 h2 元素以从中查找兄弟姐妹的方式。我会使用function 而不是检查Content Logical Definition 是否在文本内:

soup.find(lambda elm: elm.name == "h2" and "Content Logical Definition" in elm.text)

此外,要获得下一个兄弟姐妹,您应该使用 .next_siblings 而不是 nextsibilings

演示:

>>> from bs4 import BeautifulSoup
>>> html3= """<a name="definition"> </a>
... <h2><span class="sectioncount">3.342.2323</span> Content Logical Definition <a title="link to here" class="self-link" href="valueset-investigation"><img src="ta.png"/></a></h2>
... <hr/>
... <div><p from the following </p><ul><li>Include these codes as defined in http://snomed.info/sct<table><tr><td><b>Code</b></td><td><b>Display</b></td></tr><tr><td>34353553</td><td>Examination / signs</td><td/></tr><tr><td>35453453453</td><td>History/symptoms</td><td/></tr></table></li></ul></div>
... <p> </p>"""
>>> soup = BeautifulSoup(html3, "lxml")
>>> h2 = soup.find(lambda elm: elm.name == "h2" and "Content Logical Definition" in elm.text)
>>> for sibling in h2.next_siblings:
...     print(sibling)
... 
<hr/>
<div><p following="" from="" the=""></p><ul><li>Include these codes as defined in http://snomed.info/sct<table><tr><td><b>Code</b></td><td><b>Display</b></td></tr><tr><td>34353553</td><td>Examination / signs</td><td></td></tr><tr><td>35453453453</td><td>History/symptoms</td><td></td></tr></table></li></ul></div>
<p> </p>

虽然,现在知道你正在处理的真正的 HTML 以及它有多混乱,我认为你应该迭代兄弟姐妹,在下一个 h2 或者如果你在此之前找到一个 table 时中断。实际实现:

import requests
from bs4 import BeautifulSoup

urls = [
    'https://www.hl7.org/fhir/valueset-activity-reason.html',
    'https://www.hl7.org/fhir/valueset-age-units.html'
]

for url in urls:
    r = requests.get(url)
    soup = BeautifulSoup(r.content, 'lxml')

    h2 = soup.find(lambda elm: elm.name == "h2" and "Content Logical Definition" in elm.text)
    table = None
    for sibling in h2.find_next_siblings():
        if sibling.name == "table":
            table = sibling
            break
        if sibling.name == "h2":
            break
    print(table)

【讨论】:

  • 谢谢!,我的主要目的是找到“table”和“ul”作为下一个兄弟姐妹。但是在这部分代码“h2.next_siblings中的兄弟:”之后,如果你写一个代码:“如果兄弟名称==“表”:打印“2”(例如),它没有。似乎它不考虑 或
      作为下一个兄弟姐妹。但是如果适用于“div”。
    • @Mary 当然,我想你可以这样使用find_next()table = h2.find_next("table")
    • 非常感谢!现在的问题是:它将找到 h2 之后的所有表。虽然我只想要在“内容逻辑定义”部分定义的表。换句话说,如果“内容逻辑定义”中没有定义表,我希望代码“table = h2.find_next(“table”)”中的表为空。你有什么建议?再次感谢!
    • @Mary 好的,为了获得更好的上下文,您能否提供完整的输入 HTML 和所需的输出?谢谢!
    • @thanks alecxe !,这是我试图提取信息的两个网页的链接。我只需要“内容逻辑定义”部分的信息,所以如果本部分没有定义表,我将为表中定义的所有字段定义“null”:hl7.org/fhir/valueset-activity-reason.htmlhl7.org/fhir/valueset-account-status.html
猜你喜欢
  • 2021-02-14
  • 1970-01-01
  • 2021-03-18
  • 1970-01-01
  • 2015-03-12
  • 1970-01-01
  • 2010-10-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多