【问题标题】:Get an element before a string with Beautiful Soup使用 Beautiful Soup 在字符串之前获取一个元素
【发布时间】:2017-05-15 00:40:24
【问题描述】:

我正在使用 Beautiful Soup 在网站上搜索一组整数值,并生成一个与名称匹配的列表。但是,我遇到的问题是该网站对我需要的元素(“列表项”)使用了一些非常模糊的类名,这些元素在其他元素中重现,我不想抓住这些元素。到目前为止,我的代码如下所示:

from bs4 import BeautifulSoup as bs
import requests

url = "http://beautifulnumberssite.com/"
html = requests.get(url).text
soup = bs(html)

names = soup.findAll("h1", class_="th1")
stats = soup.findAll("li", class_="list-item")

print(names, stats)

但是,这也返回了一大堆我不想要的东西。有没有办法让它变得如此 Beautiful Soup 只返回后跟某个字符串的元素的内容?因此,如果网页包含如下部分:

<li class='list-item'>
<strong>65</strong>
Important Values
</li>
<li class='list-item'>
<strong>49</strong>
Useless Values
</li>

我希望能够设置 Beautiful Soup/Python 来解析像“重要值”这样的字符串,并直接在它之前获取元素(忽略任何换行符或空格),或者更好的是其中包含的值元素。所以在这种情况下,Beautiful Soup 会打印:

<strong>65</strong>

或者,更优选地,只是:

65

这可能吗?

【问题讨论】:

  • 当然,接受哪个答案是您的选择,但如果您选择当前接受的答案,您的问题就会过于复杂。如果您可以直接获得所需的值,为什么要遍历所有列表项?另外,如果可以获取文本并直接将其转换为int,为什么还要获取contents 列表?
  • 好点。我将查看新答案并找出最适合我的答案。感谢您抽出宝贵时间提供额外的答案。非常感激。我敢肯定,如果我目前能够的话,我会同时投两票。但你也说得对,我应该花时间好好检查一下新的。

标签: python string python-2.7 parsing beautifulsoup


【解决方案1】:

我希望能够设置 Beautiful Soup/Python 来解析像“重要值”这样的字符串,并直接在它之前获取元素(忽略任何换行符或空格),或者更好的是其中包含的值元素

BeautifulSoup 在定位元素方面非常灵活。有各种技术可以在 HTML 中查找元素。在这种情况下,我们可以找到“重要值”文本节点并找到preceding strong element

important_values = int(soup.find(text=lambda text: text and text.strip() == 'Important Values').find_previous_sibling("strong").get_text())
print(important_values)  # prints 65

或者,我们可以创建一个"search function" 并检查strong 元素名称和下一个文本兄弟节点是否为“重要值”:

def search_function(tag):
    is_strong = tag.name == "strong"
    is_important = tag.next_sibling and tag.next_sibling.strip() == 'Important Values'
    return is_strong and is_important

important_values = int(soup.find(search_function).get_text())
print(important_values)  # prints 65

【讨论】:

  • 在进一步测试中,我发现当不存在任何值或当前值不是预期类型时,此解决方案会出错。
【解决方案2】:

只需迭代您的类元素并检查它们的内容是否与您的重要字符串匹配:

for listItem in soup.findAll('li', class_='list-item'):
    if listItem.decode_contents(formatter="html").find('Important Values') != -1:
        print(listItem.find('strong').contents)        

【讨论】:

  • 这很好,谢谢,但由于某种原因,它输出的是[u'65'],而不是预期的['65']。你知道为什么会这样吗?
  • 我认为这是因为它是一个 unicode 字符串,这就是 python2.7 管理它们的方式。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-10-09
  • 2019-07-10
  • 2021-10-15
  • 1970-01-01
  • 1970-01-01
  • 2022-01-18
  • 1970-01-01
相关资源
最近更新 更多