BeautifulSoup解析空格

今天爬一個網站,它的class裏有空格,致使我用BeautifulSoup半天沒爬出來,後來看了文檔,這叫多值屬性:css

HTML 4定義了一系列能夠包含多個值的屬性.在HTML5中移除了一些,卻增長更多.最多見的多值的屬性是 class (一個tag能夠有多個CSS的class). 還有一些屬性 rel , rev , accept-charset , headers , accesskey . 在Beautiful Soup中多值屬性的返回類型是list:html

1 css_soup = BeautifulSoup('<p class="body strikeout"></p>')
2 css_soup.p['class']
3 # ["body", "strikeout"]
4 
5 css_soup = BeautifulSoup('<p class="body"></p>')
6 css_soup.p['class']
7 # ["body"]

 

若是某個屬性看起來好像有多個值,但在任何版本的HTML定義中都沒有被定義爲多值屬性,那麼Beautiful Soup會將這個屬性做爲字符串返回python

1 id_soup = BeautifulSoup('<p id="my id"></p>')
2 id_soup.p['id']
3 # 'my id'

 

將tag轉換成字符串時,多值屬性會合併爲一個值正則表達式

1 rel_soup = BeautifulSoup('<p>Back to the <a rel="index">homepage</a></p>')
2 rel_soup.a['rel']
3 # ['index']
4 rel_soup.a['rel'] = ['index', 'contents']
5 print(rel_soup.p)
6 # <p>Back to the <a rel="index contents">homepage</a></p>

 

若是轉換的文檔是XML格式,那麼tag中不包含多值屬性post

1 xml_soup = BeautifulSoup('<p class="body strikeout"></p>', 'xml')
2 xml_soup.p['class']
3 # u'body strikeout'

 

這是文檔對多值屬性的解釋網站

因此在使用BeautifulSoup.find or BeautifulSoup.find_all的時候要注意spa

 

舉個例子吧:code

假如我如今的HTML是這樣的:orm

>>> html = '<div class="l_post j_l_post l_post_bright  "></div>'

先對他用html.parser解析,而後咱們看一看裏面的class是什麼xml

1 >>> Soup = BeautifulSoup(html,'html.parser')
2 >>> Soup.div['class']
3 ['l_post', 'j_l_post', 'l_post_bright', '']

咦,咱們發現若是最後又空格的話會多一個'',咱們用find_all或者find能夠找到咱們想要的這個標籤,可是class能夠只要第一個,也能夠要整個列表均可以

notice:我在爬一個網站的時候發現了這個的問題,你用列表的化是隻要有列表中任一一個元素都能匹配上

1 >>> Soup.find('div', attrs = {'class':'1_post'})
2 >>> Soup.find('div', attrs = {'class':'l_post'})
3 <div class="l_post j_l_post l_post_bright "></div>
4 >>> Soup.find('div', attrs = {'class':['l_post', 'j_l_post']})
5 <div class="l_post j_l_post l_post_bright "></div>
6 >>> Soup.find('div', attrs = {'class':['l_post', 'j_l_post', 'l_post_bright']})
7 <div class="l_post j_l_post l_post_bright "></div>
8 >>> Soup.find('div', attrs = {'class':['l_post', 'j_l_post', 'l_post_bright', '']})
9 <div class="l_post j_l_post l_post_bright "></div>

 

這裏再補充一點知識吧,就是find,和find_all的用法,拿這個例子繼續(對了,find_all由於經常使用,全部能夠省略,能夠直接寫Soup(.....))

1 >>> Soup.find(attrs = {'class':['l_post', 'j_l_post', 'l_post_bright', '']})
2 <div class="l_post j_l_post l_post_bright "></div>
3 >>> Soup.find_all(attrs = {'class':['l_post', 'j_l_post', 'l_post_bright', '']})[0]
4 <div class="l_post j_l_post l_post_bright "></div>
5 >>> Soup.find_all('div', attrs = {'class':['l_post', 'j_l_post', 'l_post_bright', '']})[0]
6 <div class="l_post j_l_post l_post_bright "></div>

 

通過對BeautifulSoup的深度閱讀後,以爲下面這個點對分析多值屬性的html很重要:

按照CSS類名搜索tag的功能很是實用,但標識CSS類名的關鍵字 class 在Python中是保留字,使用 class 作參數會致使語法錯誤.從Beautiful Soup的4.1.1版本開始,能夠經過 class_ 參數搜索有指定CSS類名的tag:

1 soup.find_all("a", class_="sister")
2 # [<a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>,
3 #  <a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>,
4 #  <a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>]

class_ 參數一樣接受不一樣類型的 過濾器 ,字符串,正則表達式,方法或 True :

 1 soup.find_all(class_=re.compile("itl"))
 2 # [<p class="title"><b>The Dormouse's story</b></p>]
 3 
 4 def has_six_characters(css_class):
 5     return css_class is not None and len(css_class) == 6
 6 
 7 soup.find_all(class_=has_six_characters)
 8 # [<a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>,
 9 #  <a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>,
10 #  <a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>]

tag的 class 屬性是 多值屬性 .按照CSS類名搜索tag時,能夠分別搜索tag中的每一個CSS類名:

1 css_soup = BeautifulSoup('<p class="body strikeout"></p>')
2 css_soup.find_all("p", class_="strikeout")
3 # [<p class="body strikeout"></p>]
4 
5 css_soup.find_all("p", class_="body")
6 # [<p class="body strikeout"></p>]

搜索 class 屬性時也能夠經過CSS值徹底匹配:

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

徹底匹配 class 的值時,若是CSS類名的順序與實際不符,將搜索不到結果:

1 soup.find_all("a", attrs={"class": "sister"})
2 # [<a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>,
3 #  <a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>,
4 #  <a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>]

 

以上是文檔對class_的解釋,可是我發如今有些網站的解析時這種方式仍是行不通,因此在這種方式行不通的時候,我用了這種re

 1 InfoList = Soup.find_all(class_ = re.compile('l_post j_l_post l_post_bright')) 

好比說這個多值屬性,我用前面的方法都不行,tag的class是「l_post j_l_post l_post_bright  」,這樣才解決了個人問題

相關文章
相關標籤/搜索