2015-06-23 65 views
1

我想獲得具有data-a屬性的標籤。我相信選擇正確的選擇會返回一個空白列表。BeautifulSoup選擇器無法匹配任意標籤?

如何使用CSS選擇器成功選擇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]: [] 

回答

2

這是BeautifulSoup CSS選擇器實現中的已知限制;它只會將屬性名稱與字母,數字和下劃線相匹配,而不是破折號。見issue #1304007

您仍然可以選擇帶有find_all()呼叫的那些元素:

>>> 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>]