使用正则表达式从HTML中提取所有的值

3

我需要一个提醒来完成这个脚本。

我正在爬取一个新闻通讯网站以获取特定的子字符串。目的是解析页面中称为提到的公司..的特定部分,并将每个公司的名称放入列表数据类型中。

目前为止,以下是我已经完成的内容,它可以正常工作,但只能获取第一项:

from bs4 import BeautifulSoup as bs4
import requests
import re

url = 'http://news.hipsternomics.com/issues/how-much-is-your-personal-data-worth-on-the-black-market-148489'
r = requests.get(url).text
soup = bs4(r, 'html.parser')
companies = []
for elem in soup(text=re.compile(r'^(.*?Companies mentioned\b)')):
    companies.append(elem)    

预期结果:

  • 我想将“提到的公司”列入列表,如下所示: [谷歌、苹果、特斯拉、耐克、TJX、罗斯、L品牌、多米诺骨牌]

同时也欢迎采用其他方式来改进正则表达式函数,以捕获类似于“本期提到的公司:”或“提到的公司:”等异常情况,如此处所见:这里。 谢谢。


通常使用正则表达式解析HTML是一个非常糟糕的想法。你应该依赖于一个功能齐全的XML/HTML解析器。 - Pinke Helga
2个回答

2

您可以通过提供 div 类的值来访问内容:

import requests, re
from bs4 import BeautifulSoup as soup
d = soup(requests.get('http://news.hipsternomics.com/issues/how-much-is-your-personal-data-worth-on-the-black-market-148489').text, 'html.parser')
new_d = [i for i in d.find_all('div', {'class':'revue-p'}) if 'Companies mentioned' in i.text][0]
*final_results, _ = [re.sub('^[\w\s]+[,\s:]+|^[,\s]+|\s+$', '', i) for i in new_d.contents if isinstance(i, str)]

输出:

['Google', 'Apple', 'Tesla', 'Nike', 'TJX', 'Ross', 'L Brands', 'Domino’s']

请问最后一行左侧的语法是什么意思?看起来像是解包。 - QHarr
1
@QHarr 是的,这是解包。_ 被称为占位符变量。 - Ajax1234
@QHarr 很高兴能帮忙! - Ajax1234
非常有帮助。谢谢。你使用了什么工具来构建正则表达式函数? - ezeagwulae

2
你想实现的目标仅使用正则表达式是无法完成的。捕获组只能捕获一个内容,你无法动态地捕获多个组。此文章提供了进一步的解释:点击查看
我的建议是先获取所有公司的字符串。
all_companies = re.search(r'Companies mentioned YTD:\s(.*)', orig_text).group(1)
print(all_companies, '\n')

接下来,按照,进行字符串分割。

companies_percent = all_companies.split(', ')

# print(companies_percent, '\n')
# Output
# ['Google -1%', 'Apple 0%', 'Tesla +15%', 'Nike +17%', 'TJX +18%', 'Ross -2%', 'L Brands -47%', 'Domino’s +37%'] 

最后,将公司名称后面的百分号去掉。
companies = list(map(lambda x: re.search(r'(.*)\s[\+|-]?\d+%', x).group(1), companies_percent))

# print(companies, '\n')
# Output
# ['Google', 'Apple', 'Tesla', 'Nike', 'TJX', 'Ross', 'L Brands', 'Domino’s'] 

把所有东西都放在一起:
import re
from bs4 import BeautifulSoup as bs4
import requests

url = 'http://news.hipsternomics.com/issues/how-much-is-your-personal-data-worth-on-the-black-market-148489'
r = requests.get(url).text
soup = bs4(r, 'html.parser')

all_companies = re.search(r'Companies mentioned YTD:\s(.*)', soup.get_text()).group(1)
companies_percent = all_companies.split(', ')
companies = list(map(lambda x: re.search(r'(.*)\s[\+|-]?\d+%', x).group(1), companies_percent))

可运行示例请参见https://repl.it/@hanxue/capturingrepeatedtextgrouppython


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接