Beautifulsoup怎么找到所有的工作

时间:2016-08-09 00:08:09

标签: python html beautifulsoup html-parsing

我注意到了findAll方法的一些奇怪行为:

>>> htmls="<html><body><p class=\"pagination-container\">slytherin</p><p class=\"pagination-container and something\">gryffindor</p></body></html>"
>>> soup=BeautifulSoup(htmls, "html.parser")
>>> for i in soup.findAll("p",{"class":"pagination-container"}):
    print(i.text)


slytherin
gryffindor
>>> for i in soup.findAll("p", {"class":"pag"}):
    print(i.text)


>>> for i in soup.findAll("p",{"class":"pagination-container"}):
    print(i.text)


slytherin
gryffindor
>>> for i in soup.findAll("p",{"class":"pagination"}):
    print(i.text)


>>> len(soup.findAll("p",{"class":"pagination-container"}))
2
>>> len(soup.findAll("p",{"class":"pagination-containe"}))
0
>>> len(soup.findAll("p",{"class":"pagination-contai"}))
0
>>> len(soup.findAll("p",{"class":"pagination-container and something"}))
1
>>> len(soup.findAll("p",{"class":"pagination-conta"}))
0

因此,当我们搜索pagination-container时,它会返回第一个和第二个p标记。它让我觉得它寻找部分平等:类似if passed_string in class_attribute_value:。所以我缩短了findAll方法中的字符串,它从来没有找到任何东西!

这怎么可能?

1 个答案:

答案 0 :(得分:4)

首先,class是一个特殊的multi-valued space-delimited attribute并且有特殊处理。

当您撰写soup.findAll("p", {"class":"pag"})时,BeautifulSoup会搜索包含pag类的元素。它将按空格分割元素类值,并检查分割项目中是否有pag。如果您的元素包含class="test pag"class="pag",则会匹配。

请注意,如果soup.findAll("p", {"class": "pagination-container and something"})BeautifulSoup将匹配具有完全class属性值的元素。在这种情况下不涉及分裂 - 它只是看到有一个元素,其中完整的class值等于所需的字符串。

要在其中一个类上进行部分匹配,您可以提供regular expressiona function作为类过滤器值:

import re

soup.find_all("p", {"class": re.compile(r"pag")})  # contains pag
soup.find_all("p", {"class": re.compile(r"^pag")})  # starts with pag

soup.find_all("p", {"class": lambda class_: class_ and "pag" in class_})  # contains pag
soup.find_all("p", {"class": lambda class_: class_ and class_.startswith("pag")})  # starts with pag

还有很多话要说,但您也应该知道BeautifulSoupCSS selector支持(有限的一个,但涵盖了大多数常见用例)。你可以这样写:

soup.select("p.pagination-container")  # one of the classes is "pagination-container"
soup.select("p[class='pagination-container']")  # match the COMPLETE class attribute value
soup.select("p[class^=pag]")  # COMPLETE class attribute value starts with pag

class中处理BeautifulSoup属性值是混淆和问题的常见来源,请参阅这些相关主题以获得更多理解: