在BeautifulSoup中将CSS选择器与轴组合器一起使用时,我有些困惑。以下是说明我的意思的简单代码:
from bs4 import BeautifulSoup as bs
import requests
response = requests.get('https://stackoverflow.com/questions/tagged/python')
soup = bs(response.text)
print(len(soup.select('#mainbar > div')))
返回6
个孩子...但是
print(len(soup.select('#mainbar>div')))
返回0
个孩子...
与'#mainbar ~ div'
(发现1个兄弟姐妹)和#mainbar~div'
(没有发现任何东西)相同
在documentation中,这些空格是可选的,但实际上,对于相同的选择器,我使用BeautifulSoup获得了不同的输出(我认为)
是bs4
错误还是此行为取决于CSS版本或其他?
答案 0 :(得分:3)
已确认是这里的错误:https://bugs.launchpad.net/beautifulsoup/+bug/1717851
从CSS角度来看,选择器可以使用/不使用。
我会看看是否能找到进一步的证据。
报告错误的个人指出:
据我所见,问题在于,由于代码仅在执行
shlex.split
,不会将div
,>
和span
视为单独的对象 实体是>
两侧的空白。
答案 1 :(得分:2)
如果要对其进行修补,请参见bs4/element.py
第1440行替换
tokens = shlex.split(selector)
使用
selector = re.sub(r'\s*([+>~])\s*', r' \1 ', selector)
tokens = shlex.split(selector)
演示:
<script type="text/javascript" src="//cdn.datacamp.com/dcl-react.js.gz"></script>
<div data-datacamp-exercise data-lang="python">
<code data-type="sample-code">
import re, shlex
def testSelect(selector):
selector = re.sub(r'\s*([+>~])\s*', r' \1 ', selector)
tokens = shlex.split(selector)
print(tokens)
testSelect('#mainbar > div ~ p') # default
testSelect('#mainbar>div~p')
testSelect('#mainbar >div+ p')
testSelect('#mainbar.classA')
testSelect('#mainbar p')
</code>
</div>