CSS组合器周围的空格是否真的是可选的

时间:2018-11-20 21:21:49

标签: python web-scraping beautifulsoup css-selectors

在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版本或其他?

2 个答案:

答案 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>