BeautifulSoup 选择器无法匹配任意标签?

BeautifulSoup selectors fail to match arbitary tags?

我想获取具有 data-a 属性的标签。 select或者我认为是正确的 returns 空白列表。

如何成功 select 与 CSS select 或标签与 data-a

In [53]: s = BeautifulSoup("<div data-a='12'></div>")

In [54]: s
Out[54]: <html><body><div data-a="12"></div></body></html>


In [55]: s.select('div')
Out[55]: [<div data-a="12"></div>]

In [56]: s.select('[data-a]')
Out[56]: []

这是 BeautifulSoup CSS select 或实现中的一个已知限制;它只会匹配带有 字母、数字和下划线 的属性名称,而不匹配破折号。参见 issue #1304007

您仍然可以通过 find_all() 调用 select 这些元素:

>>> s.find_all(**{'data-a': True})
[<div data-a="12"></div>]

**{..} 应用任意关键字参数; data-a 不是有效的 Python 标识符,因此我们需要使用变通方法。 True 表示 具有此属性的任何元素

您也可以修补代码以接受属性名称中的破折号:

import re
from bs4 import PageElement

PageElement.attribselect_re = re.compile(
    r'^(?P<tag>\w+)?\[(?P<attribute>[\w-]+)(?P<operator>[=~\|\^$\*]?)' +
    r'=?"?(?P<value>[^\]"]*)"?\]$'
    )

使用更新后的表达式将属性与破折号匹配:

>>> import re
>>> from bs4 import PageElement
>>> s.select('[data-a]')
[]
>>> PageElement.attribselect_re = re.compile(
...     r'^(?P<tag>\w+)?\[(?P<attribute>[\w-]+)(?P<operator>[=~\|\^$\*]?)' +
...     r'=?"?(?P<value>[^\]"]*)"?\]$'
...     )
>>> s.select('[data-a]')
[<div data-a="12"></div>]