使用BeautifulSoup

时间:2019-08-20 17:23:52

标签: python html web-scraping beautifulsoup recompile

我正在尝试对该页面的某些部分进行网页抓取: https://markets.businessinsider.com/stocks/bp-stock 使用BeautifulSoup搜索表h2标题中包含的一些文本

当我这样做:

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

它可以正确获取我要的表。

当我尝试使用类似的行获取表“ Analyst Opinion”时,它返回None:

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

我猜测html代码中可能有一些特殊字符,它们可以按预期提供功能。 我也尝试过:

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

没有成功。

我想通过查找是否包含我所请求的文本来获取包含此文本“分析师意见”的表,而不查找所有表。

任何想法都会受到高度赞赏。 最好

1 个答案:

答案 0 :(得分:1)

您可以使用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=' '))