Beautiful Soup4學(xué)習(xí)筆記(四):搜索文檔樹

Beautiful Soup定義了很多搜索方法,這里著重介紹2個(gè): find() 和 find_all() .其它方法的參數(shù)和用法類似,請讀者舉一反三.

使用 find_all() 類似的方法可以查找到想要查找的文檔內(nèi)容:

過濾器

介紹 find_all() 方法前,先介紹一下過濾器的類型 ,這些過濾器貫穿整個(gè)搜索的API.
過濾器可以被用在tag的name種论衍,節(jié)點(diǎn)的屬性中,字符串中或他們的混合中聚磺。

字符串

最簡單的過濾器就是字符串坯台。在搜索方法中傳入一個(gè)字符串參數(shù),Beautiful Soup會(huì)查找與字符串完整匹配的內(nèi)容,下面的例子用于查找文檔中所有的<b>標(biāo)簽:

>>> soup.find_all('b') 
[<b>The Dormouse's story</b>]

如果傳入字節(jié)碼參數(shù),Beautiful Soup會(huì)當(dāng)作UTF-8編碼,可以傳入一段Unicode 編碼來避免Beautiful Soup解析編碼出錯(cuò)

正則表達(dá)式

如果傳入正則表達(dá)式作為參數(shù),Beautiful Soup會(huì)通過正則表達(dá)式的 match() 來匹配內(nèi)容.下面例子中找出所有以b開頭的標(biāo)簽,這表示<body>和<b>標(biāo)簽都應(yīng)該被找到:

>>> import re  
>>> for tag  in soup.find_all(re.compile("^b")):
...     print(tag.name) 
...     
... 
body
b

下面代碼找出所有名字中包含”t”的標(biāo)簽:

 >>> for  tag in soup.find_all(re.compile("t")):
...     print(tag.name)  
...     
... 
html
title

列表

如果傳入列表參數(shù),Beautiful Soup會(huì)將與列表中任一元素匹配的內(nèi)容返回.下面代碼找到文檔中所有<a>標(biāo)簽和<b>標(biāo)簽:

>>> soup.find_all(["a","b"]) 
[<b>The Dormouse's story</b>, <a class="sister"  id="link1">Elsie</a>, <a class="siste
r"  id="link2">Lacie</a>, <a class="sister"  id="link3
">Tillie</a>]

True

True可以匹配任何值,下面的代碼查找到所有的tag瘫寝,但是不會(huì)返回字符串節(jié)點(diǎn):

>>> for tag in soup.find_all(True): 
...     print(tag.name)   
...     
... 
html
head
title
body
p
b
p
a
a
a
p

方法

如果沒有合適過濾器蜒蕾,那么還可以定義一個(gè)方法,方法只接受一個(gè)元素參數(shù)矢沿,如果這個(gè)方法返回True表示當(dāng)前元素匹配被找到滥搭,如果不是則返回False
下面方法校驗(yàn)了當(dāng)前元素,如果包含 class 屬性卻不包含 id 屬性,那么將返回 True:

>>> def has_class_but_no_id(tag):
...     return tag.has_attr('class') and  not tag.has_attr('id') 
... 
#將這個(gè)方法作為參數(shù)傳入find_all()方法,將得到所有<p>標(biāo)簽:

>>> soup.find_all(has_class_but_no_id) 
[<p class="title"><b>The Dormouse's story</b></p>, <p class="story">Once upon a time there were three little sisters;
 and their names were
<a class="sister"  id="link1">Elsie</a>,
<a class="sister"  id="link2">Lacie</a> and
<a class="sister"  id="link3">Tillie</a>;
and they lived at the bottom of a well.</p>, <p class="story">...</p>]

注意:并沒有生效捣鲸,改天問個(gè)大神看看

通過一個(gè)方法來過濾一類標(biāo)簽屬性的時(shí)候, 這個(gè)方法的參數(shù)是要被過濾的屬性的值, 而不是這個(gè)標(biāo)簽. 下面的例子是找出 href 屬性不符合指定正則的 a 標(biāo)簽.

>>> def not_lacie(href):
...     return   href and not re.compile("lacie").search(href) 
... 
>>> soup.find_all(href=not_lacie)
[<a class="sister"  id="link1">Elsie</a>, <a class="sister" href="http://example.com/t
illie" id="link3">Tillie</a>]

標(biāo)簽過濾方法可以使用復(fù)雜方法. 下面的例子可以過濾出前后都有文字的標(biāo)簽.

>>> from bs4 import NavigableString
>>> def surrounded_by_strings(tag):
...     return ( isinstance(tag.next_element,NavigableString)  and isinstance(tag.previous_element,NavigableString))
... 
>>> for tag in soup.find_all(surrounded_by_strings): 
...     print(tag.name)   
...     
... 
body
p
a
a
a
p

find_all()

find_all(name,attrs,recursive,string,**kwargs)
find_all() 方法搜索當(dāng)前tag的所有tag子節(jié)點(diǎn),并判斷是否符合過濾器的條件.這里有幾個(gè)例子:

>>> soup.find_all('title')
[<title>The Dormouse's story</title>]
>>> soup.find_all("p","title") 
[<p class="title"><b>The Dormouse's story</b></p>]
>>> soup.find_all("a")
[<a class="sister"  id="link1">Elsie</a>, <a class="sister"  id="link2
">Lacie</a>, <a class="sister"  id="link3">Tillie</a>]
>>> soup.find_all(id = "link2") 
[<a class="sister"  id="link2">Lacie</a>]
>>> import re   
>>> soup.find(string = re.compile("sisters") 
... )
'Once upon a time there were three little sisters; and their names were\n'

有幾個(gè)方法很相似,還有幾個(gè)方法是新的,參數(shù)中的 string 和 id 是什么含義? 為什么 find_all("p", "title") 返回的是CSS Class為”title”的<p>標(biāo)簽? 我們來仔細(xì)看一下 find_all() 的參數(shù)

name參數(shù)

name參數(shù)可以查找所有名字為name的tag,字符串對象會(huì)被自動(dòng)忽略掉闽坡。
簡單的用法如下:

>>> soup.find_all("title")
[<title>The Dormouse's story</title>]

注意:搜索name參數(shù)的值可以使用任一類型的過濾器栽惶,字符串,正則表達(dá)式疾嗅,列表外厂,方法或是True。

keyword參數(shù)

如果一個(gè)指定名字的參數(shù)不是搜索內(nèi)置的參數(shù)名代承,搜索時(shí)會(huì)把該參數(shù)當(dāng)作指定名字tag的屬性來搜索汁蝶,如果包含一個(gè)名字為 id 的參數(shù),Beautiful Soup會(huì)搜索每個(gè)tag的”id”屬性.

>>> soup.find_all(id = "link2")  
[<a class="sister"  id="link2">Lacie</a>]

如果傳入 href 參數(shù),Beautiful Soup會(huì)搜索每個(gè)tag的”href”屬性:

>>> soup.find_all(href=re.compile("elsie")) 
[<a class="sister"  id="link1">Elsie</a>]

搜索指定名字的屬性時(shí)可以使用的參數(shù)值包括 字符串 , 正則表達(dá)式 , 列表, True .
下面的例子在文檔樹中查找所有包含 id 屬性的tag,無論 id 的值是什么:

>>> soup.find_all(id=True) 
[<a class="sister"  id="link1">Elsie</a>, <a class="sister"  id="link2
">Lacie</a>, <a class="sister"  id="link3">Tillie</a>]

使用多個(gè)指定名字的參數(shù)可以同時(shí)過濾tag的多個(gè)屬性:

>>> soup.find_all(href=re.compile("elsie"), id='link1')
[<a class="sister"  id="link1">Elsie</a>]

有些tag屬性在搜索不能使用,比如HTML5中的 data-* 屬性:

>>> data_soup = BeautifulSoup('<div data-foo="value">foo!</div>') 
>>> data_soup.find_all(data-foo="value") 
  File "<input>", line 1
SyntaxError: keyword can't be an expression

但是可以通過find_all()方法的attrs參數(shù)定義一個(gè)字典參數(shù)來搜索包含特殊屬性的tag:

>>> data_soup.find_all(attrs={"data-foo":"value"}) 
[<div data-foo="value">foo!</div>]

按CSS搜索

按照CSS類名搜索tag的功能非常實(shí)用,但標(biāo)識(shí)CSS類名的關(guān)鍵字 class 在Python中是保留字,使用 class 做參數(shù)會(huì)導(dǎo)致語法錯(cuò)誤.從Beautiful Soup的4.1.1版本開始,可以通過 class_ 參數(shù)搜索有指定CSS類名的tag:

>>> soup.find_all("a",class_="sister") 
[<a class="sister"  id="link1">Elsie</a>, <a class="sister"  id="link2
">Lacie</a>, <a class="sister"  id="link3">Tillie</a>]

class_ 參數(shù)同樣接受不同類型的 過濾器 ,字符串,正則表達(dá)式,方法或 True :

>>> soup.find_all(class_=re.compile("itl")) 
[<p class="title"><b>The Dormouse's story</b></p>]
>>> def has_six_characters(css_class):
...     return css_class is not None and len(css_class) == 6 
...  
>>> soup.find_all(class_=has_six_characters) 
[<a class="sister"  id="link1">Elsie</a>, <a class="sister"  id="link2
">Lacie</a>, <a class="sister"  id="link3">Tillie</a>]

tag的 class
屬性是 多值屬性 .按照CSS類名搜索tag時(shí),可以分別搜索tag中的每個(gè)CSS類名:

>>> css_soup = BeautifulSoup('<p class="body strikeout"></p>') 
>>> css_soup.find_all("p", class_="strikeout") 
[<p class="body strikeout"></p>]
>>> 
>>> css_soup.find_all("p", class_="body") 
[<p class="body strikeout"></p>]

搜索 class 屬性時(shí)也可以通過CSS值完全匹配:

>>> css_soup.find_all("p", class_="body strikeout")
[<p class="body strikeout"></p>]

完全匹配 class 的值時(shí),如果CSS類名的順序與實(shí)際不符,將搜索不到結(jié)果:

>>> soup.find_all("a",attrs={"class":"sister"}) 
[<a class="sister"  id="link1">Elsie</a>, <a class="sister"  id="link2
">Lacie</a>, <a class="sister"  id="link3">Tillie</a>]

string參數(shù)

通過 string 參數(shù)可以搜搜文檔中的字符串內(nèi)容.與 name 參數(shù)的可選值一樣, string 參數(shù)接受 字符串 , 正則表達(dá)式 , 列表, True . 看例子:

>>> soup.find_all(string="Elsie")
['Elsie']
>>> 
>>> soup.find_all(string=["Tillie", "Elsie", "Lacie"])
['Elsie', 'Lacie', 'Tillie']
>>> soup.find_all(string=re.compile("Dormouse"))
["The Dormouse's story", "The Dormouse's story"]

>>> def is_the_only_string_within_a_tag(s):
...     #""Return True if this string is the only child of its parent tag.""
...     return (s == s.parent.string) 
...  
... 
>>> soup.find_all(string=is_the_only_string_within_a_tag) 
["The Dormouse's story", "The Dormouse's story", 'Elsie', 'Lacie', 'Tillie', '...']

雖然 string 參數(shù)用于搜索字符串,還可以與其它參數(shù)混合使用來過濾tag.Beautiful Soup會(huì)找到 .string 方法與 string 參數(shù)值相符的tag.下面代碼用來搜索內(nèi)容里面包含“Elsie”的<a>標(biāo)簽

>>> soup.find_all("a", string="Elsie") 
[<a class="sister"  id="link1">Elsie</a>]

limit參數(shù)

find_all() 方法返回全部的搜索結(jié)構(gòu),如果文檔樹很大那么搜索會(huì)很慢.如果我們不需要全部結(jié)果,可以使用 limit 參數(shù)限制返回結(jié)果的數(shù)量.效果與SQL中的limit關(guān)鍵字類似,當(dāng)搜索到的結(jié)果數(shù)量達(dá)到 limit 的限制時(shí),就停止搜索返回結(jié)果.

文檔樹中有3個(gè)tag符合搜索條件,但結(jié)果只返回了2個(gè),因?yàn)槲覀兿拗屏朔祷財(cái)?shù)量:

>>> soup.find_all("a", limit=2) 
[<a class="sister"  id="link1">Elsie</a>, <a class="sister"  id="link2
">Lacie</a>]

recursive參數(shù)

調(diào)用tag的 find_all() 方法時(shí),Beautiful Soup會(huì)檢索當(dāng)前tag的所有子孫節(jié)點(diǎn),如果只想搜索tag的直接子節(jié)點(diǎn),可以使用參數(shù) recursive=False .
一段簡單的文檔:

<html>
 <head>
  <title>
   The Dormouse's story
  </title>
 </head>
...

是否使用 recursive 參數(shù)的搜索結(jié)果:

>>> html_doc = """
... <html>
...  <head>
...   <title>
...    The Dormouse's story
...   </title>
...  </head>
... ...
... """
>>> soup = BeautifulSoup(html_doc, 'html.parser')   
>>> soup.html.find_all("title") 
[<title>
   The Dormouse's story
  </title>]
>>> soup.html.find_all("title",recursive=False) 
[]

<title>標(biāo)簽在 <html> 標(biāo)簽下, 但并不是直接子節(jié)點(diǎn), <head> 標(biāo)簽才是直接子節(jié)點(diǎn). 在允許查詢所有后代節(jié)點(diǎn)時(shí) Beautiful Soup 能夠查找到 <title> 標(biāo)簽. 但是使用了 recursive=False 參數(shù)之后,只能查找直接子節(jié)點(diǎn),這樣就查不到 <title> 標(biāo)簽了.

Beautiful Soup 提供了多種DOM樹搜索方法. 這些方法都使用了類似的參數(shù)定義. 比如這些方法: find_all(): name, attrs, text, limit. 但是只有 find_all() 和 find() 支持 recursive 參數(shù).

像調(diào)用find_all()一樣調(diào)用tag

find_all() 幾乎是Beautiful Soup中最常用的搜索方法,所以我們定義了它的簡寫方法. BeautifulSoup 對象和 tag 對象可以被當(dāng)作一個(gè)方法來使用,這個(gè)方法的執(zhí)行結(jié)果與調(diào)用這個(gè)對象的 find_all() 方法相同,下面兩行代碼是等價(jià)的:

>>> soup.find_all("a") 
[<a class="sister"  id="link1">Elsie</a>, <a class="sister" href="http://example.com/l
acie" id="link2">Lacie</a>, <a class="sister"  id="link3">Tillie</a>]
>>> soup("a")
[<a class="sister"  id="link1">Elsie</a>, <a class="sister" href="http://example.com/l
acie" id="link2">Lacie</a>, <a class="sister"  id="link3">Tillie</a>]

這兩行代碼也是等價(jià)的:

>>> soup.title.find_all(string=True) 
["The Dormouse's story"]
>>> soup.title(string=True) 
["The Dormouse's story"]
>>> 

find()

find(name,attrs,recursive,string,**kwargs)
find_all() 方法將返回文檔中符合條件的所有tag,盡管有時(shí)候我們只想得到一個(gè)結(jié)果.比如文檔中只有一個(gè)<body>標(biāo)簽,那么使用 find_all() 方法來查找<body>標(biāo)簽就不太合適, 使用 find_all 方法并設(shè)置 limit=1 參數(shù)不如直接使用 find() 方法.下面兩行代碼是等價(jià)的:

>>> soup.find_all("title",limit=1)
[<title>The Dormouse's story</title>]
>>> soup.find("title") 
<title>The Dormouse's story</title>

唯一的區(qū)別是dind_all()方法返回的結(jié)果是包含值的元素列表,而find()函數(shù)直接返回結(jié)果论悴。

find_all() 方法沒有找到目標(biāo)是返回空列表, find() 方法找不到目標(biāo)時(shí),返回 None .

>>> print(soup.find("nojscnef"))
None

soup.head.title是tag的名字方法的簡寫掖棉,這個(gè)簡寫的原理就是多次調(diào)用當(dāng)前tag的find()方法:

>>> soup.head.title
<title>The Dormouse's story</title>
>>> soup.find("head").find("title") 
<title>The Dormouse's story</title>

find_parents()和find_parent()

find_parents(name,attrs,recursive,string,kwargs)
find_parent(name,attrs,recursive,string,
kwargs)
我們已經(jīng)用了很大篇幅來介紹 find_all() 和 find() 方法,Beautiful Soup中還有10個(gè)用于搜索的API.它們中的五個(gè)用的是與 find_all() 相同的搜索參數(shù),另外5個(gè)與 find() 方法的搜索參數(shù)類似.區(qū)別僅是它們搜索文檔的不同部分.

注意:find_all()和find()只搜索當(dāng)前節(jié)點(diǎn)的所有子節(jié)點(diǎn),子孫節(jié)點(diǎn)等膀估。find_parents()和find_parent()用來搜索當(dāng)前節(jié)點(diǎn)的父輩節(jié)點(diǎn)幔亥,搜索方法與普通的tag的搜索方法相同,搜索文檔包含的內(nèi)容察纯。我們從一個(gè)文檔中的一個(gè)葉子節(jié)點(diǎn)開始:

>>> a_string  = soup.find(string = "Lacie") 
>>> a_string 
'Lacie'
>>> a_string.find_parents("a")
[<a class="sister"  id="link2">Lacie</a>]
>>> a_string.find_parent("p") 
<p class="story">Once upon a time there were three little sisters; and their names were
<a class="sister"  id="link1">Elsie</a>,
<a class="sister"  id="link2">Lacie</a> and
<a class="sister"  id="link3">Tillie</a>;
and they lived at the bottom of a well.</p>

>>> a_string.find_parents("p","title")
[]

文檔中的一個(gè)<a>標(biāo)簽是當(dāng)前葉子節(jié)點(diǎn)的直接父節(jié)點(diǎn),所以可以被找到.還有一個(gè)<p>標(biāo)簽,是目標(biāo)葉子節(jié)點(diǎn)的間接父輩節(jié)點(diǎn),所以也可以被找到.包含class值為”title”的<p>標(biāo)簽不是不是目標(biāo)葉子節(jié)點(diǎn)的父輩節(jié)點(diǎn),所以通過 find_parents() 方法搜索不到.

find_parent() 和 find_parents() 方法會(huì)讓人聯(lián)想到 .parent 和 .parents 屬性.它們之間的聯(lián)系非常緊密.搜索父輩節(jié)點(diǎn)的方法實(shí)際上就是對 .parents 屬性的迭代搜索.

find_next_siblings()和find_next_sibling()

find_next_siblings( name , attrs , recursive , string , **kwargs )
find_next_sibling( name , attrs , recursive , string , **kwargs )

這2個(gè)方法通過 .next_siblings 屬性對當(dāng)tag的所有后面解析 [5] 的兄弟tag節(jié)點(diǎn)進(jìn)行迭代, find_next_siblings() 方法返回所有符合條件的后面的兄弟節(jié)點(diǎn), find_next_sibling()只返回符合條件的后面的第一個(gè)tag節(jié)點(diǎn).

>>> first_link = soup.a  
>>> first_link 
<a class="sister"  id="link1">Elsie</a>
>>> first_link.find_next_siblings("a") 
[<a class="sister"  id="link2">Lacie</a>, <a class="sister" href="http://example.com/t
illie" id="link3">Tillie</a>]
>>> first_story_paragraph = soup.find("p","story") 
>>> first_story_paragraph.find_next_sibling("p") 
<p class="story">...</p>

find_previous_siblings() 和 find_previous_sibling()

find_previous_siblings( name , attrs , recursive , string , **kwargs )
find_previou_siblings( name , attrs , recursive , string , **kwargs )

這2個(gè)方法通過 .previous_siblings 屬性對當(dāng)前tag的前面解析 [5] 的兄弟tag節(jié)點(diǎn)進(jìn)行迭代, find_previous_siblings() 方法返回所有符合條件的前面的兄弟節(jié)點(diǎn), find_previous_sibling() 方法返回第一個(gè)符合條件的前面的兄弟節(jié)點(diǎn):

>>> last_link = soup.find("a",id = "link3") 
>>> last_link 
<a class="sister"  id="link3">Tillie</a>
>>> last_link.find_previous_siblings("a") 
[<a class="sister"  id="link2">Lacie</a>, <a class="sister" href="http://example.com/e
lsie" id="link1">Elsie</a>]
>>> first_story_paragraph = soup.find("p", "story")
>>> first_story_paragraph.find_previous_sibling("p")
<p class="title"><b>The Dormouse's story</b></p>

find_all_next()和find_next()

find_all_next( name , attrs , recursive , string , **kwargs )
find_next( name , attrs , recursive , string , **kwargs )

這2個(gè)方法通過 .next_elements 屬性對當(dāng)前tag的之后的 tag和字符串進(jìn)行迭代, find_all_next() 方法返回所有符合條件的節(jié)點(diǎn), find_next() 方法返回第一個(gè)符合條件的節(jié)點(diǎn):

>>> first_link = soup.a 
>>> first_link  
<a class="sister"  id="link1">Elsie</a>
>>> first_link.find_all_next(string=True) 
['Elsie', ',\n', 'Lacie', ' and\n', 'Tillie', ';\nand they lived at the bottom of a well.', '\n', '...', '\n']
>>> first_link.find_next("p") 
<p class="story">...</p>

第一個(gè)例子中,字符串 “Elsie”也被顯示出來,盡管它被包含在我們開始查找的<a>標(biāo)簽的里面.第二個(gè)例子中,最后一個(gè)<p>標(biāo)簽也被顯示出來,盡管它與我們開始查找位置的<a>標(biāo)簽不屬于同一部分.例子中,搜索的重點(diǎn)是要匹配過濾器的條件,并且在文檔中出現(xiàn)的順序而不是開始查找的元素的位置.

find_all_previous()和find_previous()

find_all_previous( name , attrs , recursive , string , **kwargs )
find_previous( name , attrs , recursive , string , **kwargs )

這2個(gè)方法通過 .previous_elements 屬性對當(dāng)前節(jié)點(diǎn)前面 的tag和字符串進(jìn)行迭代, find_all_previous() 方法返回所有符合條件的節(jié)點(diǎn), find_previous() 方法返回第一個(gè)符合條件的節(jié)點(diǎn).

>>> first_link = soup.a 
>>> first_link 
<a class="sister"  id="link1">Elsie</a>
>>> first_link.find_all_previous("p")
[<p class="story">Once upon a time there were three little sisters; and their names were
<a class="sister"  id="link1">Elsie</a>,
<a class="sister"  id="link2">Lacie</a> and
<a class="sister"  id="link3">Tillie</a>;
and they lived at the bottom of a well.</p>, <p class="title"><b>The Dormouse's story</b></p>]

find_all_previous("p") 返回了文檔中的第一段(class=”title”的那段),但還返回了第二段,<p>標(biāo)簽包含了我們開始查找的<a>標(biāo)簽.不要驚訝,這段代碼的功能是查找所有出現(xiàn)在指定<a>標(biāo)簽之前的<p>標(biāo)簽,因?yàn)檫@個(gè)<p>標(biāo)簽包含了開始的<a>標(biāo)簽,所以<p>標(biāo)簽一定是在<a>之前出現(xiàn)的.

CSS選擇器

Beautiful Soup支持大部分的CSS選擇器帕棉,在Tag或BeautifSoup對象的.select()方法中傳入字符串參數(shù),既可以使用CSS選擇器的語法找到tag:

>>> soup.select("title") 
[<title>The Dormouse's story</title>]

通過tag標(biāo)簽逐層查找:

>>> soup.select("body a")
[<a class="sister"  id="link1">Elsie</a>, <a class="sister" href="http://example.com/l
acie" id="link2">Lacie</a>, <a class="sister"  id="link3">Tillie</a>]
>>> soup.select("html head title") 
[<title>The Dormouse's story</title>]

找到某個(gè)tag標(biāo)簽下的直接子標(biāo)簽:

>>> soup.select("head > title") 
[<title>The Dormouse's story</title>]
>>> soup.select("p > a") 
[<a class="sister"  id="link1">Elsie</a>, <a class="sister" href="http://example.com/l
acie" id="link2">Lacie</a>, <a class="sister"  id="link3">Tillie</a>]
>>> soup.select("p > #link1") 
[<a class="sister"  id="link1">Elsie</a>]
>>> soup.select("body > a") 
[]
>>> soup.select("p > a:nth-of-type(2)") 
[<a class="sister"  id="link2">Lacie</a>]

找到兄弟節(jié)點(diǎn):

>>> soup.select("#link1 ~ .sister") 
[<a class="sister"  id="link2">Lacie</a>, <a class="sister" href="http://example.com/t
illie" id="link3">Tillie</a>]
>>> soup.select("#link1 + .sister") 
[<a class="sister"  id="link2">Lacie</a>]

通過CSS的類名查找:

>>> soup.select(".sister") 
[<a class="sister"  id="link1">Elsie</a>, <a class="sister" href="http://example.com/l
acie" id="link2">Lacie</a>, <a class="sister"  id="link3">Tillie</a>]

>>> soup.select("[class~=sister]")
[<a class="sister"  id="link1">Elsie</a>, <a class="sister" href="http://example.com/l
acie" id="link2">Lacie</a>, <a class="sister"  id="link3">Tillie</a>]

通過tag的id查找:

>>> soup.select("#link1")
[<a class="sister"  id="link1">Elsie</a>]
>>> soup.select("a#link1")
[<a class="sister"  id="link1">Elsie</a>]

同時(shí)用多種CSS選擇器查詢元素:

>>> soup.select("#link1,#link2") 
[<a class="sister"  id="link1">Elsie</a>, <a class="sister" href="http://example.com/l
acie" id="link2">Lacie</a>]

通過是否存在某個(gè)屬性來查找:

>>> soup.select("a[href]")
[<a class="sister"  id="link1">Elsie</a>, <a class="sister" href="http://example.com/l
acie" id="link2">Lacie</a>, <a class="sister"  id="link3">Tillie</a>]

通過屬性的值來查找:

>>> soup.select('a[) 
[<a class="sister"  id="link1">Elsie</a>]
>>> soup.select('a[href^="http://example.com/"]') 
[<a class="sister"  id="link1">Elsie</a>, <a class="sister" href="http://example.com/l
acie" id="link2">Lacie</a>, <a class="sister"  id="link3">Tillie</a>]
>>> soup.select('a[href$="tillie"]') 
[<a class="sister"  id="link3">Tillie</a>]
>>> soup.select('a[href*=".com/el"]') 
[<a class="sister"  id="link1">Elsie</a>]

通過語言設(shè)置來查找:

>>> multilingual_markup = """
...  <p lang="en">Hello</p>
...  <p lang="en-us">Howdy, y'all</p>
...  <p lang="en-gb">Pip-pip, old fruit</p>
...  <p lang="fr">Bonjour mes amis</p>
... """ 

>>> multilingual_soup = BeautifulSoup(multilingual_markup)
>>> multilingual_soup.select('p[lang|=en]')
[<p lang="en">Hello</p>, <p lang="en-us">Howdy, y'all</p>, <p lang="en-gb">Pip-pip, old fruit</p>]

返回查找到的元素的第一個(gè)

>>> soup.select_one(".sister") 
<a class="sister"  id="link1">Elsie</a>
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末饼记,一起剝皮案震驚了整個(gè)濱河市香伴,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌具则,老刑警劉巖即纲,帶你破解...
    沈念sama閱讀 219,427評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異乡洼,居然都是意外死亡崇裁,警方通過查閱死者的電腦和手機(jī)匕坯,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,551評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來拔稳,“玉大人葛峻,你說我怎么就攤上這事“捅龋” “怎么了术奖?”我有些...
    開封第一講書人閱讀 165,747評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長轻绞。 經(jīng)常有香客問我采记,道長,這世上最難降的妖魔是什么政勃? 我笑而不...
    開封第一講書人閱讀 58,939評論 1 295
  • 正文 為了忘掉前任唧龄,我火速辦了婚禮,結(jié)果婚禮上奸远,老公的妹妹穿的比我還像新娘既棺。我一直安慰自己,他們只是感情好懒叛,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,955評論 6 392
  • 文/花漫 我一把揭開白布丸冕。 她就那樣靜靜地躺著,像睡著了一般薛窥。 火紅的嫁衣襯著肌膚如雪胖烛。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,737評論 1 305
  • 那天诅迷,我揣著相機(jī)與錄音佩番,去河邊找鬼。 笑死竟贯,一個(gè)胖子當(dāng)著我的面吹牛答捕,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播屑那,決...
    沈念sama閱讀 40,448評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼拱镐,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了持际?” 一聲冷哼從身側(cè)響起沃琅,我...
    開封第一講書人閱讀 39,352評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎蜘欲,沒想到半個(gè)月后益眉,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,834評論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,992評論 3 338
  • 正文 我和宋清朗相戀三年郭脂,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了年碘。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,133評論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡展鸡,死狀恐怖屿衅,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情莹弊,我是刑警寧澤涤久,帶...
    沈念sama閱讀 35,815評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站忍弛,受9級(jí)特大地震影響响迂,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜细疚,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,477評論 3 331
  • 文/蒙蒙 一蔗彤、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧惠昔,春花似錦幕与、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,022評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽潮饱。三九已至来氧,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間香拉,已是汗流浹背啦扬。 一陣腳步聲響...
    開封第一講書人閱讀 33,147評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留凫碌,地道東北人扑毡。 一個(gè)月前我還...
    沈念sama閱讀 48,398評論 3 373
  • 正文 我出身青樓,卻偏偏與公主長得像盛险,于是被迫代替她去往敵國和親瞄摊。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,077評論 2 355

推薦閱讀更多精彩內(nèi)容