BeautifulSoup:查找具有相同值的多个属性类型



有没有一种方法可以使用bs4搜索具有相同值的多个属性类型?

我正在从新闻文章中抓取元标签,以便获得标题、作者和发布数据等信息。站点之间的数据结构存在一些差异,我想使用最紧凑的代码来覆盖已知的可能性。

例如,标题可以是以下任意一种:

<meta content="Title of the article" property="og:title"/>
<meta content="Title of the article" property="title"/>
<meta name="Title of the article" property="og:title"/>
<meta name="Title of the article" property="title"/>

我可以这样做:

try:
soup.find('meta', {'property' : re.compile('title')})['content']
except:
soup.find('name', {'property' : re.compile('title')})['content']

但如果我能做这样的事情那就太好了:

## No result returned
soup.find('meta', {re.compile('property|name') : re.compile('title')})
## TypeError: unhashable type: 'list'
soup.find('meta', {['property','name'] : re.compile('title')})

沿着这些路线有什么可行的吗?

主要的挑战是属性命名可能会有所不同,因此应该对列表['name','title','content','...']的有效值进行检查,该列表可以外包给一个单独的函数。

仅选择属性包含标题<meta>,我使用css selectors:

soup.select_one('meta[property*="title"]')

将元素推入函数并迭代其属性,同时检查它们是否与可能的名称匹配:

def get_title(e):
for a in e.attrs:
if a in ['name','content']:
return e.get(a)
title = get_title(soup.select_one('meta[property*="title"]'))

下面的例子应该说明如何在列表理解的基础上实现整个事情由于新闻页面可能只包含其中一个组合,因此结果将是一个只有一个元素或没有元素的列表,这取决于属性是否存在

from bs4 import BeautifulSoup
html='''
<meta content="Title of the article" property="og:title"/>
<meta content="Title of the article" property="title"/>
<meta name="Title of the article" property="og:title"/>
<meta name="Title of the article" property="title"/>
<meta title="Title of the article" property="title"/>
'''
soup = BeautifulSoup(html)
[t.get(a) for t in soup.select('meta[property*="title"]') for a in t.attrs if a in ['name','title','content']]

据我所知,您希望在html代码中找到多个具有相同文件夹名称的对象。

content_metas = soup.find_all("meta", {"content": "Title of the article"})

name_metas = soup.find_all("meta", {"name": "Title of the article"})

最新更新