免费视频淫片aa毛片_日韩高清在线亚洲专区vr_日韩大片免费观看视频播放_亚洲欧美国产精品完整版

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開通VIP
【Python爬蟲學(xué)習(xí)筆記(3)】Beautiful Soup庫(kù)相關(guān)知識(shí)點(diǎn)總結(jié)


1. Beautiful Soup簡(jiǎn)介

    Beautiful Soup是將數(shù)據(jù)從HTML和XML文件中解析出來(lái)的一個(gè)python庫(kù),它能夠提供一種符合習(xí)慣的方法去遍歷搜索和修改解析樹,這將大大減少爬蟲程序的運(yùn)行時(shí)間。

    Beautiful Soup自動(dòng)將輸入文檔轉(zhuǎn)換為Unicode編碼,輸出文檔轉(zhuǎn)換為utf-8編碼。你不需要考慮編碼方式,除非文檔沒有指定一個(gè)編碼方式,這時(shí),Beautiful Soup就不能自動(dòng)識(shí)別編碼方式了。然后,你僅僅需要說(shuō)明一下原始編碼方式就可以了。

    Beautiful Soup已成為和lxml、html6lib一樣出色的python解釋器,為用戶靈活地提供不同的解析策略或強(qiáng)勁的速度。

 

2. Beautiful Soup安裝

   利用pip可以迅速安裝,目前最新版本為BeautifulSoup4。

1 $ pip install beautifulsoup4

    安裝后,import一下bs4就可以使用了。

1 from bs4 import BeautifulSoup

 

3. 創(chuàng)建Beautiful Soup對(duì)象

   我們利用以下測(cè)試文件來(lái)進(jìn)行之后的總結(jié)。

 1 html = """ 2 <html><head><title>The Dormouse's story</title></head> 3 <body> 4 <p class="title" name="dromouse"><b>The Dormouse's story</b></p> 5 <p class="story">Once upon a time there were three little sisters; and their names were 6 <a  class="sister" id="link1"><!-- Elsie --></a>, 7 <a  class="sister" id="link2">Lacie</a> and 8 <a  class="sister" id="link3">Tillie</a>; 9 and they lived at the bottom of a well.</p>10 <p class="story">...</p>11 """

    import之后,創(chuàng)建一個(gè)BeautifulSoup對(duì)象如下參數(shù)可以是一個(gè)抓取到的unicode格式的網(wǎng)頁(yè)html,也可以是一個(gè)已經(jīng)保存到本地的html文件test.html。

1 soup = BeautifulSoup(html)2 soup = BeautifulSoup(open('test.html'))

    創(chuàng)建后查看是否創(chuàng)建成功。注意:有時(shí)需要在后面加上encode('utf-8')來(lái)進(jìn)行編碼才能將soup對(duì)象正確顯示出來(lái)。

1 print soup.prettify()

 

4. 四種Beautiful Soup對(duì)象類型

    Beautiful Soup一共有四大對(duì)象種類,包括Tag,NavigableString,BeautifulSoup和Comment。

4.1 Tag

Tag對(duì)象

    Tag就是html文件中的標(biāo)簽以及標(biāo)簽之間的內(nèi)容,例如以下就是一個(gè)Tag。

1 <title>The Dormouse's story</title>

    可以這樣得到title這個(gè)Tag,第二行為運(yùn)行結(jié)果。

1 print soup.title2 #<title>The Dormouse's story</title>

    注意:如果得到的是'bs4.element.Tag'類型的對(duì)象可以繼續(xù)進(jìn)行后續(xù)的.操作,即能進(jìn)行soup對(duì)象所能進(jìn)行的操作,所以需要確保一個(gè)對(duì)象是'bs4.element.Tag'類型后再進(jìn)行后續(xù)對(duì)其的操作,例如后面將介紹的.find方法是Tag對(duì)象才擁有的。

1 print type(soup.title)2 #<class 'bs4.element.Tag'>

Tag方法

.name

    Tag對(duì)象的.name方法得到的是該Tag的標(biāo)簽本身名稱。

1 print soup.title.name2 #title

.attrs

    Tag對(duì)象的.attrs將得到標(biāo)簽中所有屬性的字典。

1 print soup.p.attrs2 #{'class': ['title'], 'name': 'dromouse'}

    可以對(duì)Tag對(duì)象進(jìn)行字典可以進(jìn)行的操作,例如修改,刪除,讀取等。

 1 print soup.p['class']#讀?。ǚ椒ㄒ唬?/span> 2 #['title'] 3 print soup.p.get('class')#讀?。ǚ椒ǘ?/span> 4 #['title'] 5  6 soup.p['class']="newClass"#修改 7 print soup.p 8 #<p class="newClass" name="dromouse"><b>The Dormouse's story</b></p> 9 10 del soup.p['class']#刪除11 print soup.p12 #<p name="dromouse"><b>The Dormouse's story</b></p>

4.2 NavigableString

    標(biāo)簽內(nèi)部的內(nèi)容由.string方法可以得到,且這些內(nèi)容為'bs4.element.NavigableString'類型的對(duì)象。

1 print soup.p.string2 #The Dormouse's story3 4 print type(soup.p.string)5 #<class 'bs4.element.NavigableString'>

4.3 BeautifulSoup

    BeautifulSoup 對(duì)象表示的是一個(gè)文檔的全部?jī)?nèi)容.大部分時(shí)候,可以把它當(dāng)作 Tag 對(duì)象,是一個(gè)特殊的 Tag。

1 print type(soup.name)2 #<type 'unicode'>3 print soup.name 4 # [document]5 print soup.attrs 6 #{} 空字典

4.4 Comment

    前三種類型幾乎涵蓋了在HTML或者XML中所有的內(nèi)容,但是Comment類型是需要關(guān)心的一種,和CData,ProcessingInstruction,Declaration,Doctype一樣,它是NavigableString類型的一個(gè)子類,通過(guò)以下代碼可以簡(jiǎn)單了解它的功能。

 1 markup = "<b><!--Hey, buddy. Want to buy a used parser?--></b>"#標(biāo)簽中內(nèi)容為注釋 2 soup = BeautifulSoup(markup) 3 comment = soup.b.string 4 type(comment) 5 # <class 'bs4.element.Comment'> 6 comment 7 # u'Hey, buddy. Want to buy a used parser' 8 print(soup.b.prettify()) 9 # <b>10 #  <!--Hey, buddy. Want to buy a used parser?-->11 # </b>

    注意:標(biāo)簽里的內(nèi)容實(shí)際上是注釋,但是如果我們利用 .string 來(lái)輸出它的內(nèi)容,我們發(fā)現(xiàn)它已經(jīng)把注釋符號(hào)去掉了,所以這可能會(huì)給我們帶來(lái)不必要的麻煩,需要在使用或者進(jìn)行一些操作 之前進(jìn)行類型判斷。

1 if type(soup.b.string)==bs4.element.Comment:2     ...

 

5. 樹的遍歷

5.1 子孫節(jié)點(diǎn)

.content

    Tag對(duì)象的.content方法可以得到其子節(jié)點(diǎn)的一個(gè)列表表示。

1 print soup.head.contents 2 #[<title>The Dormouse's story</title>]

    當(dāng)然,既然是列表可以用索引直接得到某一項(xiàng)。

1 print soup.head.contents[0]2 #<title>The Dormouse's story</title>

.children

    Tag對(duì)象的.children方法得到一個(gè)其子節(jié)點(diǎn)的迭代器,可以遍歷之獲取其中的元素。

1 for child in  soup.body.children:2     print child

.descendants

    與.content和.children只得到直接子節(jié)點(diǎn)不同,.descendants能對(duì)所有子孫節(jié)點(diǎn)迭代循環(huán),將標(biāo)簽層層剝離得到所有子節(jié)點(diǎn),同樣通過(guò)遍歷的方法得到每個(gè)子孫節(jié)點(diǎn)。

1 for child in soup.descendants:2     print child

5.2 父親節(jié)點(diǎn)

.parent

    Tag對(duì)象的.parent方法能得到其直接父節(jié)點(diǎn)。

.parents

    用.parents屬性可以遞歸得到元素的所有父節(jié)點(diǎn)。

1 content = soup.head.title.string2 for parent in  content.parents:3     print parent.name4 #title5 #head6 #html7 #[document]

5.3 兄弟節(jié)點(diǎn)

.next_sibling和.next_siblings

    .next_sibling得到Tag對(duì)象平級(jí)的下一個(gè)節(jié)點(diǎn),如果不存在則返回None。.next_siblings得到Tag對(duì)象平級(jí)的下面所有兄弟節(jié)點(diǎn)。

.previous_sibling和.previous_siblings

    .previous_sibling得到Tag對(duì)象平級(jí)的上一個(gè)節(jié)點(diǎn),如果不存在則返回None。.next_siblings得到Tag對(duì)象平級(jí)的上面所有兄弟節(jié)點(diǎn)。

    注意:由于在HTML文檔中的空白和換行也被視作是一個(gè)節(jié)點(diǎn),所以可能得到的兄弟節(jié)點(diǎn)(或者子節(jié)點(diǎn)父節(jié)點(diǎn))會(huì)是空白類型或者字符串類型而不是Tag,所以在進(jìn)行下一步操作時(shí)一定要先用type函數(shù)進(jìn)行類型的判斷。

5.4 前后節(jié)點(diǎn)

.next_element和.next_elements

    與 .next_sibling和.next_siblings 不同,它并不是針對(duì)于兄弟節(jié)點(diǎn),而是在所有節(jié)點(diǎn),不分層次得到下一個(gè)節(jié)點(diǎn)和所有的后續(xù)節(jié)點(diǎn)。.next_elements的結(jié)果通過(guò)遍歷訪問。

.previous_element和.previous_elements

    這兩個(gè)方法將不分層次得到上一個(gè)節(jié)點(diǎn)和所有之前的節(jié)點(diǎn)。.previous_elements的結(jié)果通過(guò)遍歷訪問。

5.4 節(jié)點(diǎn)內(nèi)容

.string

    如果一個(gè)標(biāo)簽里面沒有標(biāo)簽了,那么 .string 就會(huì)返回標(biāo)簽里面的內(nèi)容。如果標(biāo)簽里面只有唯一的一個(gè)標(biāo)簽了,那么 .string 也會(huì)返回最里面的內(nèi)容。

1 print soup.head.string2 #The Dormouse's story3 print soup.title.string4 #The Dormouse's story

    而如果Tag包含了多個(gè)子節(jié)點(diǎn),Tag就無(wú)法確定.string 方法應(yīng)該調(diào)用哪個(gè)子節(jié)點(diǎn)的內(nèi)容,輸出結(jié)果是 None。

.strings和.stripped_strings

    當(dāng)一個(gè)Tag對(duì)象有多個(gè)子節(jié)點(diǎn)時(shí),可以用.strings方法再通過(guò)遍歷獲得所有子節(jié)點(diǎn)的內(nèi)容。

 1 for string in soup.strings: 2     print(repr(string)) 3     # u"The Dormouse's story" 4     # u'\n\n' 5     # u"The Dormouse's story" 6     # u'\n\n' 7     # u'Once upon a time there were three little sisters; and their names were\n' 8     # u'Elsie' 9     # u',\n'10     # u'Lacie'11     # u' and\n'12     # u'Tillie'13     # u';\nand they lived at the bottom of a well.'14     # u'\n\n'15     # u'...'16     # u'\n'

    用.stripped_strings方法可以得到過(guò)濾掉空格和空行的內(nèi)容。

.get_text()

    如果你僅僅想要得到文檔或者標(biāo)簽的文本部分,可以使用.get_text()方法,它能以一個(gè)單一的一個(gè)Unicode串的形式返回文檔中或者Tag對(duì)象下的所有文本。

1 markup = '<a >\nI linked to <i>example.com</i>\n</a>'2 soup = BeautifulSoup(markup)3 4 soup.get_text()5 #u'\nI linked to example.com\n'6 soup.i.get_text()7 #u'example.com'

    你可以指定一個(gè)字符串來(lái)連接文本的位。

1 soup.get_text("|")2 #u'\nI linked to |example.com|\n'

    進(jìn)一步,通過(guò)strip去除掉文本每個(gè)位的頭尾空白。

1 soup.get_text("|", strip=True)2 #u'I linked to|example.com'

    用列表推導(dǎo)式以及.stripped_strings方法羅列出文本內(nèi)容。

1 [text for text in soup.stripped_strings]2 #[u'I linked to', u'example.com']

 

6. 樹的搜索

6.1 find_all(name, attrs, recursive, string, limit, **kwargs)

    該方法將搜索當(dāng)前Tag對(duì)象的所有子節(jié)點(diǎn),并且按照過(guò)濾條件得到篩選后對(duì)象的列表。

name參數(shù)

1)傳字符串

    最簡(jiǎn)單的方法是傳入標(biāo)簽名的字符串,可以得到所有以該字符串為標(biāo)簽名的一個(gè)列表。

1 print soup.find_all('a')2 #[<a class="sister"  id="link1"><!-- Elsie --></a>, <a class="sister"  id="link2">Lacie</a>, <a class="sister"  id="link3">Tillie</a>]

2)傳正則表達(dá)式

    可以通過(guò)傳正則表達(dá)式得到符合表達(dá)式規(guī)則的Tag對(duì)象。

1 import re2 for tag in soup.find_all(re.compile("^b")):3     print(tag.name)4 # body5 # b

3)傳列表

    可以傳入一個(gè)字符串的列表,將匹配列表中標(biāo)簽的Tag全部返回。

1 soup.find_all(["a", "b"])2 # [<b>The Dormouse's story</b>,3 #  <a class="sister"  id="link1">Elsie</a>,4 #  <a class="sister"  id="link2">Lacie</a>,5 #  <a class="sister"  id="link3">Tillie</a>]

4)傳True

    True參數(shù)將匹配文檔中所有的節(jié)點(diǎn),但是不包括文本字符串。

 1 for tag in soup.find_all(True): 2     print(tag.name) 3 # html 4 # head 5 # title 6 # body 7 # p 8 # b 9 # p10 # a11 # a12 # a13 # p

5)傳入函數(shù)

    可以根據(jù)函數(shù)返回值的True/False來(lái)得到匹配的節(jié)點(diǎn)。

1 def has_class_but_no_id(tag):2     return tag.has_attr('class') and not tag.has_attr('id')3 4 soup.find_all(has_class_but_no_id)5 # [<p class="title"><b>The Dormouse's story</b></p>,6 #  <p class="story">Once upon a time there were...</p>,7 #  <p class="story">...</p>]

關(guān)鍵字參數(shù)

    可以傳入一個(gè)或者多個(gè)關(guān)鍵字,BeautifulSoup會(huì)搜索當(dāng)前Tag下的每一個(gè)節(jié)點(diǎn)的該關(guān)鍵字及其對(duì)應(yīng)的值。

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

    特殊:如果希望用class及其值作為過(guò)濾條件,由于class是python的關(guān)鍵字,所以需要作如下處理。

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

    另外,有些tag屬性在搜索不能使用,比如HTML5中的 data-* 屬性,可以這樣來(lái)進(jìn)行過(guò)濾。

1 data_soup = BeautifulSoup('<div data-foo="value">foo!</div>')2 data_soup.find_all(attrs={"data-foo": "value"})3 # [<div data-foo="value">foo!</div>]

text參數(shù)

    可以在文檔中搜索一些字符串內(nèi)容,與name參數(shù)的可選值一樣,可以傳字符串,列表,正則表達(dá)式和True。

1 soup.find_all(text="Elsie")2 # [u'Elsie']3 4 soup.find_all(text=["Tillie", "Elsie", "Lacie"])5 # [u'Elsie', u'Lacie', u'Tillie']6 7 soup.find_all(text=re.compile("Dormouse"))8 [u"The Dormouse's story", u"The Dormouse's story"]

limit參數(shù)

    可用該參數(shù)限制返回的節(jié)點(diǎn)數(shù)目,例子中本身有3個(gè)符合的節(jié)點(diǎn),僅輸出兩個(gè)。

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

recursive參數(shù)

    將該參數(shù)設(shè)為False可限制只搜索當(dāng)前Tag的直接子節(jié)點(diǎn),可以節(jié)省很多搜索時(shí)間。

1 soup.html.find_all("title")2 # [<title>The Dormouse's story</title>]3 soup.html.find_all("title", recursive=False)4 # []

6.2. find( name , attrs , recursive , text , **kwargs )

    它與 find_all() 方法唯一的區(qū)別是 find_all() 方法的返回結(jié)果是值包含一個(gè)元素的列表,而 find() 方法直接返回結(jié)果

6.3. find_parents()和find_parent()

  find_all() 和 find() 只搜索當(dāng)前節(jié)點(diǎn)的所有子節(jié)點(diǎn),孫子節(jié)點(diǎn)等. find_parents() 和 find_parent() 用來(lái)搜索當(dāng)前節(jié)點(diǎn)的父輩節(jié)點(diǎn),搜索方法與普通tag的搜索方法相同,搜索文檔搜索文檔包含的內(nèi)容

6.4. find_next_siblings()和find_next_sibling()

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

6.5. find_previous_siblings()和find_previous_sibling()

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

6.6. find_all_next()和find_next()

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

6.7. find_all_previous()和find_previous()

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

本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
Beautiful Soup模塊詳解
Beautiful Soup 4.4.0 教程
Python 爬蟲(三):BeautifulSoup 庫(kù)
Python3中BeautifulSoup的使用方法
Python中使用Beautiful Soup庫(kù)的超詳細(xì)教程
第65天:爬蟲利器 Beautiful Soup 之遍歷文檔
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長(zhǎng)圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服