基礎(chǔ)學(xué)習(xí)——BeautifulSoup篇(2)

這一篇文章接在上一篇 基礎(chǔ)學(xué)習(xí)——BeautifulSoup篇(1) 之后把敢,今天來繼續(xù)學(xué)習(xí)BeautifulSoup

歡迎關(guān)注公眾號(hào):老白和他的爬蟲

4.遍歷文檔樹

4.7父節(jié)點(diǎn)和兄弟節(jié)點(diǎn)

父節(jié)點(diǎn)可以通過.parent.parents操作得倒

from bs4 import BeautifulSoup
if __name__ == "__main__":
     html_doc = """
        <html><head><title>The Dormouse's story</title></head>
        <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>
        """
     soup = BeautifulSoup(html_doc,'lxml')
     head_tag = soup.head
     title_tag = head_tag.contents[0]
     print(title_tag.parent) #打印title_tag的父節(jié)點(diǎn)
     link = soup.a
     for parent in link.parents: #循環(huán)打印a標(biāo)簽的父節(jié)點(diǎn)
         if parent is None:
             print(parent)
         else:
             print(parent.name)

兄弟節(jié)點(diǎn)些微有點(diǎn)不同品嚣,一個(gè)節(jié)點(diǎn)可以通過.next_sibling.previous_sibling得到它之前和之后的兄弟節(jié)點(diǎn)嫉你,同樣,也可以通過.next_siblings.previous_siblings遍歷操作得倒所有的兄弟節(jié)點(diǎn)思灌。

4.8回退和縮進(jìn)

上一個(gè)內(nèi)容講的.next_sibling.previous_sibling其實(shí)就已經(jīng)有了縮進(jìn)和回退的味道了沛豌,但是他們是不同的链峭。我們使用解析器把html文檔解析成了一個(gè)又一個(gè)事件或者說是標(biāo)簽,兄弟節(jié)點(diǎn)只能在這一級(jí)進(jìn)行前后操作谐算,然而要對(duì)整個(gè)文檔進(jìn)行操作熟尉,我們就必須使用到.next_element.previous_element。我們用上面的文檔樹來舉一個(gè)例子

last_a_tag = soup.find("a", id="link2")
print(last_a_tag.next_sibling) 
print(last_a_tag.next_element) 

print(last_a_tag.next_sibling)的輸出結(jié)果是and因?yàn)榈诙€(gè)<a>下一個(gè)兄弟節(jié)點(diǎn)是and氯夷,但是print(last_a_tag.next_element)的輸出結(jié)果是Lacie臣樱,因?yàn)榈诙€(gè)<a>下一個(gè)元素是比它低一級(jí)的字符串Lacie。這段代碼理解的畫腮考,這兩個(gè)操作也很好理解了雇毫,同理它還有.next_elements.previous_elements這兩個(gè)操作,具體怎么用不用我說了吧踩蔚,類比一下就會(huì)了棚放。

4.9. find_all()

find_all(name , attrs , text , keyword )使用.find_all()操作可以設(shè)置這些常用參數(shù)

4.9.1 name參數(shù)

.find_all()可以直接查找tag的name來找到對(duì)應(yīng)的標(biāo)簽

soup.find_all('b') #用來查找所有的<b>標(biāo)簽

4.9.2 keyword參數(shù).find_all()``.find_all()

print(soup.find_all(id='link2')) #用來查找id為link2的標(biāo)簽

.find_all()操作可以與正則表達(dá)式搭配,個(gè)人認(rèn)為這一步在查找一些特定標(biāo)簽時(shí)十分有用

import re
     #找到所有標(biāo)簽中以b開頭的標(biāo)簽
     for tag in soup.find_all(re.compile("^b")):
         print(tag.name)
     #提取所有a標(biāo)簽中包含字符串example的鏈接
     for x in soup.find_all('a',href = re.compile('example')):
         print(x.get('href'))

這里記住一點(diǎn)馅闽,.find_all()內(nèi)部的多個(gè)參數(shù)是可以同時(shí)寫的飘蚯,上面這段代碼我這樣寫也可以

for x in soup.find_all(class_ = 'sister' ,href = re.compile('example')):
         print(x.get('href'))

class應(yīng)該是python的關(guān)鍵字馍迄,所以我們這里需要用class_來表示class

4.9.3 attrs參數(shù)

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

data_soup = BeautifulSoup('<div data-foo="value">foo!</div>','lxml')
     print(data_soup.find_all(attrs={"data-foo": "value"}))

4.9.4 text參數(shù)

     print(soup.find_all(text="Elsie")) #輸出文本為Elsie的字符串
     print(soup.find_all(text=["Tillie", "Elsie", "Lacie"])) #輸出文本為列表中所包含的字符串
     print(soup.find_all(text=re.compile("Dormouse"))) #輸出文本包含Dormouse的字符串

4.9.5 limit參數(shù)

limit參數(shù)可以限制返回節(jié)點(diǎn)的數(shù)量

    print(soup.find_all('a',limit = 2)) #本身可以返回三個(gè)a標(biāo)簽,但是由于limit限制只返回兩個(gè)

4.10 find()

.find()其實(shí)就是.find_all()加上了limit = 1的操作局骤,區(qū)別于.find()返回的是結(jié)果攀圈,.find_all()返回的是集合
.find().find_all()還有其他的一些操作,這里就不一一舉例了峦甩,避免這個(gè)教程太過繁瑣赘来,只要熟練的掌握.find().find_all(),就已經(jīng)能解決很多的問題凯傲。其他的一些操作包括
find_parents(),find_parent(),find_next_siblings(),find_next_sibling(),find_previous_siblings(),find_previous_sibling(),find_all_next(),find_next(),find_all_previous(),find_previous()

4.11 CSS選擇器

這一個(gè)功能我不打算在這里說犬辰,因?yàn)檫@里能實(shí)現(xiàn)的功能在前面我們都已經(jīng)實(shí)現(xiàn)了,只不過更熟悉css的人可以選擇這種方法冰单。

5.修改文檔樹

給tag的 .string屬性賦值,就相當(dāng)于用當(dāng)前的內(nèi)容替代了原來的內(nèi)容:

     markup = '<a >I linked to <i>example.com</i></a>'
     soup = BeautifulSoup(markup,'lxml')
     tag = soup.a
     tag.string = "New link text."
     print(tag)

使用.append()方法可以像標(biāo)簽添加內(nèi)容

     markup = '<a >I linked to </a>'
     soup = BeautifulSoup(markup,'lxml')
     tag = soup.a
     print(tag)
     tag.append("haha")
     print(tag)

如果想要?jiǎng)?chuàng)建一段注釋

     from bs4 import Comment
     new_comment = soup.new_string("Nice to see you.", Comment)
     tag.append(new_comment)
     print(tag)

如果想要?jiǎng)?chuàng)建一個(gè)新的tag

     soup = BeautifulSoup("<b></b>",'lxml')
     original_tag = soup.b
     new_tag = soup.new_tag("a", )
     original_tag.append(new_tag)
     print(original_tag)
     new_tag.string = "Link text."
     print(original_tag)
    

使用'.insert()'插入具體的內(nèi)容

     markup = '<a >I linked to <i>example.com</i></a>'
     soup = BeautifulSoup(markup,'lxml')
     tag = soup.a
     tag.insert(1, "but did not endorse ") #參數(shù)1控制插入字符串的位置
     print(tag)

移除當(dāng)前tag的內(nèi)容

     tag.clear()
     print(tag)

移除當(dāng)前的tag節(jié)點(diǎn)

     a_tag = soup.a
     i_tag = soup.i.extract()
     print(a_tag)
     print(i_tag)

使用decompose()完全銷毀當(dāng)前tag節(jié)點(diǎn)

     markup = '<a >I linked to <i>example.com</i></a>'
     soup = BeautifulSoup(markup,'lxml')
     tag = soup.a
     a_tag = soup.a
     soup.i.decompose()
     print(a_tag)

使用replace_with()替換節(jié)點(diǎn)

     markup = '<a >I linked to <i>example.com</i></a>'
     soup = BeautifulSoup(markup,'lxml')
     tag = soup.a
     a_tag = soup.a
     new_tag = soup.new_tag("b")
     new_tag.string = "example.net"
     a_tag.i.replace_with(new_tag)
     print(tag)

6.輸出

.prettify()方法將BeautifulSoup的文檔樹格式化后以Unicode編碼輸出,每個(gè)XML/HTML標(biāo)簽都獨(dú)占一行

     markup = '<a >I linked to <i>example.com</i></a>'
     soup = BeautifulSoup(markup,'lxml')
     print(soup.prettify())

如果不想格式化輸出幌缝,可以選擇壓縮輸出

     print(str(soup))

如果只想得到標(biāo)簽中的文本內(nèi)容

     markup = '<a >\nI linked to <i>example.com</i>\n</a>'
     soup = BeautifulSoup(markup,'lxml')
     print(soup.get_text())
     print(soup.get_text("|")) #指定文本分隔符
     print(soup.get_text("|", strip=True)) #去除文本內(nèi)容前后空白

好了,BeautifulSoup的基礎(chǔ)知識(shí)我們已經(jīng)學(xué)習(xí)完畢了诫欠,你可以跟著這兩篇文章來學(xué)習(xí)掌握BeautifulSoup涵卵,也可以選擇把這兩篇當(dāng)作字典,當(dāng)你在寫爬蟲時(shí)來翻閱

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末荒叼,一起剝皮案震驚了整個(gè)濱河市缘厢,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌甩挫,老刑警劉巖贴硫,帶你破解...
    沈念sama閱讀 211,639評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異伊者,居然都是意外死亡英遭,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,277評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門亦渗,熙熙樓的掌柜王于貴愁眉苦臉地迎上來挖诸,“玉大人,你說我怎么就攤上這事法精《嗦桑” “怎么了?”我有些...
    開封第一講書人閱讀 157,221評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵搂蜓,是天一觀的道長(zhǎng)狼荞。 經(jīng)常有香客問我,道長(zhǎng)帮碰,這世上最難降的妖魔是什么相味? 我笑而不...
    開封第一講書人閱讀 56,474評(píng)論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮殉挽,結(jié)果婚禮上丰涉,老公的妹妹穿的比我還像新娘拓巧。我一直安慰自己,他們只是感情好一死,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,570評(píng)論 6 386
  • 文/花漫 我一把揭開白布肛度。 她就那樣靜靜地躺著,像睡著了一般投慈。 火紅的嫁衣襯著肌膚如雪贤斜。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,816評(píng)論 1 290
  • 那天逛裤,我揣著相機(jī)與錄音,去河邊找鬼猴抹。 笑死带族,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的蟀给。 我是一名探鬼主播蝙砌,決...
    沈念sama閱讀 38,957評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼跋理!你這毒婦竟也來了择克?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,718評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤前普,失蹤者是張志新(化名)和其女友劉穎肚邢,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體拭卿,經(jīng)...
    沈念sama閱讀 44,176評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡骡湖,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,511評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了峻厚。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片响蕴。...
    茶點(diǎn)故事閱讀 38,646評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖惠桃,靈堂內(nèi)的尸體忽然破棺而出浦夷,到底是詐尸還是另有隱情,我是刑警寧澤辜王,帶...
    沈念sama閱讀 34,322評(píng)論 4 330
  • 正文 年R本政府宣布劈狐,位于F島的核電站,受9級(jí)特大地震影響呐馆,放射性物質(zhì)發(fā)生泄漏懈息。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,934評(píng)論 3 313
  • 文/蒙蒙 一摹恰、第九天 我趴在偏房一處隱蔽的房頂上張望辫继。 院中可真熱鬧怒见,春花似錦、人聲如沸姑宽。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,755評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽炮车。三九已至舵变,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間瘦穆,已是汗流浹背纪隙。 一陣腳步聲響...
    開封第一講書人閱讀 31,987評(píng)論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留扛或,地道東北人绵咱。 一個(gè)月前我還...
    沈念sama閱讀 46,358評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像熙兔,于是被迫代替她去往敵國和親悲伶。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,514評(píng)論 2 348

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