使用 BeautifulSoup 使用包含的文本查找标签

Find a tag using text it contains using BeautifulSoup

我正在尝试通过网络抓取此页面的某些部分: https://markets.businessinsider.com/stocks/bp-stock 使用 BeautifulSoup 搜索 tables

的 h2 标题中包含的一些文本

当我这样做时:

data_table = soup.find('h2', text=re.compile('RELATED STOCKS')).find_parent('div').find('table')

它正确地得到了我想要的table。

当我尝试使用类似的行获取 table“分析师意见”时,它 returns None:

data_table = soup.find('h2', text=re.compile('ANALYST OPINIONS')).find_parent('div').find('table')

我猜测 html 代码中可能有一些特殊字符,使 re 可以按预期运行。 我也试过这个:

data_table = soup.find('h2', text=re.compile('.*?STOCK.*?INFORMATION.*?', re.DOTALL))

没有成功。

我想获取包含这段文本“分析师意见”的 table,而不是找到所有 table,而是通过检查是否包含我请求的文本。

任何想法将不胜感激。 最佳

您可以使用 CSS 选择器定位 <table>:

import requests
from bs4 import BeautifulSoup

url = 'https://markets.businessinsider.com/stocks/bp-stock '

soup = BeautifulSoup(requests.get(url).text, 'lxml')

table = soup.select_one('div:has(> h2:contains("Analyst Opinions")) table')

for tr in table.select('tr'):
    print(tr.get_text(strip=True, separator=' '))

打印:

2/26/2018 BP Outperform RBC Capital Markets
9/22/2017 BP Outperform BMO Capital Markets

更多关于 CSS 选择器 here


编辑:对于不区分大小写的方法,您可以将 bs4 API 与正则表达式一起使用(注意 flags=re.I)。这相当于上面的 .select() 方法:

import re
import requests
from bs4 import BeautifulSoup

url = 'https://markets.businessinsider.com/stocks/bp-stock '

soup = BeautifulSoup(requests.get(url).text, 'lxml')

h2 = soup.find(lambda t: t.name=='h2' and re.findall('analyst opinions', t.text, flags=re.I))
table = h2.find_parent('div').find('table')

for tr in table.select('tr'):
    print(tr.get_text(strip=True, separator=' '))