【问题标题】:BeautifulSoup: find all tags before stopping condition is metBeautifulSoup:在满足停止条件之前查找所有标签
【发布时间】:2017-12-09 00:57:18
【问题描述】:

我正在尝试从 HTML 文件中提取类标记,但前提是它位于给定停止点之前。我有的是:

import requests
from bs4 import BeautifulSoup

page = requests.get("https://mysite")
soup = BeautifulSoup(page.content, 'html.parser')
class_extr = soup.find_all("span", class_="myclass")

这可行,但它会找到myclass所有 个实例,而我只想要那些 之前 以下文本显示在soup 中:

<h4 class="cat-title" id="55">
 Title text N1
 <small>
  Title text N2.
 </small>
</h4>

使这个块独一无二的是Title text N 行,尤其是Title text N2. 行。之前有很多cat-title标签,所以我不能用它作为停止条件。

围绕这个块的代码如下所示:

...
<div class="myc">
<a class="bbb" href="linkhere_893">
<span class="myclass">Text893</span>
<img data-lazy="https://link893.jpg"/>
</a>
</div>
<div class="myc">
<a class="bbb" href="linkhere_96">
<span class="myclass">Text96</span>
<img data-lazy="https://link96.jpg"/>
</a>
</div>
</div><!-- This closes a list that starts above -->
<h4 class="cat-title" id="55">Title text N1 <small> Title text N2.</small></h4>
<div class="list" id="55">
<div class="myc">
<a class="bbb" href="linkhere_34">
<span class="myclass">Text34</span>
<img data-lazy="https://link34.jpg"/>
</a>
</div>
<div class="myc">
...

在上面和下面继续。

我该怎么做?

【问题讨论】:

  • h4 标签是 span.myclass 标签的子标签吗?
  • 不,不是。 (需要更多字符)
  • 您能否发布一个 HTML 结构的示例。或者至少 h4 和 span 之间的关系是什么
  • 没有关系。我只想找到所有myclass 标记before 该文本块,而不是所有出现在after 它的标记。

标签: python html beautifulsoup


【解决方案1】:

尝试使用find_all_previous()

import requests
from bs4 import BeautifulSoup

page = requests.get("https://mysite")
soup = BeautifulSoup(page.content, 'html.parser')
stop_at = soup.find("h4", class_="cat-title", id='55') # finds your stop tag
class_extr = stop_at.find_all_previous("span", class_="myclass")

如果有多个,这将在第一个 &lt;h4 class='cat-title', id=55&gt; 标记处停止。

参考:Beautiful Soup Documentation

【讨论】:

  • 这也有效,而且更加优雅和简洁,谢谢!
【解决方案2】:

这个怎么样:

page = requests.get("https://mysite")
# Split your page and unwanted string, then parse with BeautifulSoup
text = page.text.split('Title text N2.')
soup = BeautifulSoup(text[0], 'html.parser')
class_extr = soup.find_all("span", class_="myclass")

【讨论】:

  • 谢谢,这个答案也有效。现在不知道该选哪一个了。
  • 我将选择这个,因为它明确使用了我提到的独特文本。谢谢大家!
【解决方案3】:

你可以试试这样的:

from bs4 import BeautifulSoup

page = """
<html><body><p>
<span class="myclass">text 1</span>
<span class="myclass">text 2</span>
</p>
<h4 class="cat-title" id="55">
 Title text N1
 <small>
  Title text N2.
 </small>
</h4>

<p>
<span class="myclass">text 3</span>
<span class="myclass">text 4</span>
</p>
</body>
</html>
"""
soup = BeautifulSoup(page, 'html.parser')

for i in soup.find_all():
    if i.name == 'h4' and i.has_attr('class') and i['class'][0] == 'cat-title' and i.has_attr('id') and i['id'] == '55':
        if i.find("small") and i.find("small").text.strip()== "Title text N2.":
            break
    elif i.name == 'span'and i.has_attr('class') and i['class'][0] == 'myclass':
        print (i)

输出:

<span class="myclass">text 1</span>
<span class="myclass">text 2</span>

【讨论】:

  • 谢谢,但是这行不通,因为之前有很多cat-title 标签。真正让这个块与众不同的是 Title text N2. 文本(还有 Title text N1 文本,但前者更相关)。我应该提到这一点,否则会产生混乱。
  • @Gabriel 如果您需要更好的答案,您应该创建更好的示例。
  • @furas 我认为我展示的块已经足够了。我会尝试扩展它。
  • @Gabriel 您可以创建最小工作示例,以便我们运行它并查看问题。
  • 我已经更新了答案。这足够硬化还是需要我进一步硬化?
猜你喜欢
  • 1970-01-01
  • 2019-11-11
  • 1970-01-01
  • 1970-01-01
  • 2016-10-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-04-23
相关资源
最近更新 更多