【问题标题】:Selecting everything between two heading anchor tags选择两个标题锚标记之间的所有内容
【发布时间】:2021-02-07 12:09:52
【问题描述】:

我目前正在尝试为一个小项目抓取网页。但是,当尝试选择两个标题之间的所有内容时,我遇到了问题。这是我尝试选择的标题之一的示例:

<h2><a class="autolink" href="/compendium/dnd5e/Social%20Interaction#h-Long%20Rest">Long Rest</a></h2>

发现于:https://roll20.net/compendium/dnd5e/Rules:Resting/#h-Resting

这是我目前的代码:

 els = soup.select("h2:has(a:contains('Short Rest')) ~ *:has(~ h2:has(a:contains('Long Rest')))")

但是,使用它会返回所有使用的标签及其标签的列表,而不是我想的文本。所需的输出将是 h2 'Short Rest' 和 h2 'Long Rest' 之间的所有 HTML,因此本质上是描述短暂休息的文本。

我没有使用更简单的tag.next_sibling 方法的原因是该网页上有很多未标记的文本,该方法会跳过这些文本。

任何帮助将不胜感激,我已经坚持了一段时间了。

【问题讨论】:

  • Did you want an extra ) as in contains('Short Rest')) 如果您提供链接并指出我们可以测试的所需结果
  • @QHarr 啊,为那里的错字道歉,它解决了错误问题但仍然没有返回所需的结果 - 我将更新问题以证明这一点。
  • 我认为您实际上可能需要 next_sibling,因为该文本位于更高的父 div 下,并且您当前的通用兄弟组合器会错过该文本。
  • @QHarr 虽然如问题中所述,但这会跳过未标记的文本,因为它们不是通过使用 next_sibling 找到的。

标签: python css beautifulsoup


【解决方案1】:

如果我理解正确,这应该可以解决问题:

import requests
from bs4 import BeautifulSoup as bs
from bs4 import NavigableString
soup = bs(req.text,'lxml')
final_text = []
for item in soup.find("h2",text="Short Rest").next_siblings:
    if item.name=="h2":
        break
    if isinstance(item, NavigableString):        
        final_text.extend(item)
    else:
        final_text.extend(item.stripped_strings)

print("".join(final_text))

输出:

短暂的休息是一段停机时间,至少 1 小时长,在 一个角色所做的就是吃、喝、 阅读和处理伤口。一个角色可以花费一个或多个命中 在短暂休息结束时骰子,直到角色的最大数量 生命骰数,等于角色的等级。对于每个命中骰子 以这种方式花费,玩家掷骰子并添加角色的 对其进行宪法修正。角色恢复生命值等于 总数。玩家可以决定在之后花费额外的生命骰 每卷。角色在完成一个任务后恢复一些已消耗的生命骰 长休,如下所述。

【讨论】:

  • 很好地使用 .extend!
猜你喜欢
  • 2021-01-31
  • 1970-01-01
  • 1970-01-01
  • 2021-05-10
  • 1970-01-01
  • 2010-10-03
  • 1970-01-01
  • 1970-01-01
  • 2020-06-22
相关资源
最近更新 更多