Python3爬蟲(chóng)神器BeautifulSoup(三)——搜索文檔樹(shù)

搜索文檔樹(shù)里面主要講find()以及find_all()的用法喜庞。在講這兩個(gè)用法之前先來(lái)說(shuō)說(shuō)過(guò)濾器,什么過(guò)濾器呢棋返?顧名思義延都,過(guò)濾器就是按照條件過(guò)濾掉不符合的,留下符合的睛竣。那么在Python中這些條件可以是什么呢晰房?我們來(lái)依次介紹????

1.字符串(這個(gè)沒(méi)什么好講的)

2.正則表達(dá)式(不知道的可以百度一下什么意思)

3.列表:如果傳入列表參數(shù),Beautiful Soup會(huì)將與列表中任一元素匹配的內(nèi)容返回.

4.True:True可以匹配任何值

再來(lái)說(shuō)說(shuō)方法,什么時(shí)候用這個(gè)方法呢?當(dāng)你沒(méi)有合適的過(guò)濾器的時(shí)候殊者,那便可以定義一個(gè)方法与境,方法只接受一個(gè)元素,如果返回True那么表示當(dāng)前元素與之匹配并且被找到猖吴,反之將會(huì)返回false

你可以定義一個(gè)尋找包含class但是不包含id的標(biāo)簽

def has_class_but_no_id(tag):

? ? return tag.has_attr('class') and not tag.has_attr('id')


好了可以來(lái)講講find_all()和find()了


先來(lái)說(shuō)說(shuō).find_all()摔刁,它的具體使用規(guī)則如下

.find_all(tag,attributes,recursive,text,limit,keywords)

雖然這里有這么多個(gè)參數(shù)但是其實(shí)我們絕大多數(shù)時(shí)候只使用前兩個(gè)參數(shù)

那么我們一一介紹一下這些參數(shù)

tag:就是之前講的標(biāo)簽名(像<h1>什么之類(lèi)的),你可以傳入一個(gè)標(biāo)簽名或者多個(gè) 標(biāo)簽組成的列表

attributes:是一個(gè)用python字典封裝的一個(gè)標(biāo)簽的若干屬性以及其值海蔽,例如:.find_all("span",{"class":{"green","red"}})這就可以找出所有class為green和red的span標(biāo)簽

recursive:是一個(gè)遞歸參數(shù)共屈,他是一個(gè)布爾變量如果設(shè)為T(mén)rue那么會(huì)根據(jù)要求查找所有子標(biāo)簽以及子標(biāo)簽的子標(biāo)簽,如果設(shè)為False那么只會(huì)查找文檔的一級(jí)標(biāo)簽党窜。當(dāng)然他的默認(rèn)值是True拗引。一般我們也用不到去修改它。

text:他和attributes有點(diǎn)像但又很是不同幌衣,他是用標(biāo)簽里面的文本去匹配而不是標(biāo)簽的屬性

limit:只適用于find_all()方法矾削,你可以指定有多少項(xiàng)結(jié)果返回過(guò)來(lái),要注意的是豁护,設(shè)置了limit后返回的是按照順序返回的哼凯,不一定是你想要的結(jié)果。

keyword:可以讓你選擇那些具有指定屬性的標(biāo)簽择镇,例如:.find_all(id = "text")這個(gè)可以找出所有id=text的標(biāo)簽

但是要記住,不要濫用keyword括改,keyword只是BeautifulSoup中的一個(gè)冗余功能腻豌,雖然在有些場(chǎng)景下它顯得特別有用,但是任何能夠用keyword解決的問(wèn)題都可以用其他方式解決嘱能,

就上一個(gè)例子來(lái)說(shuō)

和.find_all("",{"id":"text"})是完全一樣的

接下來(lái)我們會(huì)來(lái)說(shuō)說(shuō)keyword的一些“缺點(diǎn)”

我們知道class是Python中的一個(gè)保留字,是不能當(dāng)做變量名來(lái)使用的。但是HTML標(biāo)簽中經(jīng)常會(huì)有class的屬性這時(shí)候.find_all(class = "green")就么沒(méi)有用了力试。你可以用以下方法解決

.find_all(class_="green")來(lái)代替毛仪,也就是在class后面加一個(gè)_(下劃線),但是這個(gè)方法顯得有點(diǎn)臃腫

我們完全可以用以下方法來(lái)代替.find_all("", {"class":"green"})

再順便說(shuō)一下对粪,用標(biāo)簽參數(shù)將tag以列表的形式傳入是或關(guān)系的過(guò)濾器而keyword的與的選擇器

再來(lái)說(shuō)說(shuō).find右冻,.find其實(shí)就是.find_all()的一種特殊情況,也就是limit = 1的特殊情況著拭。而.find_all()方法是返回一個(gè)列表而find方法是直接返回結(jié)果

.find_all()和.find只會(huì)去搜索子孫節(jié)點(diǎn)纱扭,如果要搜尋父節(jié)點(diǎn)的話那就要用.find_parents()和.find_parent()這個(gè)兩個(gè)的參數(shù)和.find_all()和.find()的一樣。其中.find_parents()和.parents功效相似儡遮,.find_parent()和.parent功效相似乳蛾。BeautifulSoup還有一些其他的搜索API其中一半是和find()的參數(shù)一樣一半是和.find_all()的參數(shù)一樣,

其他的幾個(gè)分別是(中括號(hào)中的是與之功效相似的):

.find_next_siblings()[.next_siblings],.find_next_sibling()[.next_sibling],.find_previous_siblings()[.previous_siblings],.find_previous_sibling()[.previous_sibling],.find_all_next()[.next_elements],.find_next()[.next_element],.find_all_previous()[.previous_elements],.find_previous()[.previous_elements]


CSS選擇器

BeautifulSoup對(duì)象支持絕大多數(shù)CSS選擇器,在Tag和BeautifulSoup對(duì)象的.select()方法中傳入字符串參數(shù)就可以找到相應(yīng)的tag(返回結(jié)果一般是列表的形式)那么我們就來(lái)說(shuō)說(shuō)它的使用方法。

1.可以直接通過(guò)標(biāo)簽選擇:

? ? ? ? ? ? ? ? 例如(還是以第二篇的那個(gè)HTML為例子):

? ? ? ? ? ? ? ? ? ? ????????soup.select("title")

????????????????????????????那么就可以得到以下結(jié)果:[<title>The Dormouse's story</title>]肃叶,通過(guò)這個(gè)方法可以得到所有title標(biāo)簽

????????????????也可以用這個(gè)語(yǔ)法:

???????????????????????????? soup.select("p:nth-of-type(3)")

? ? ? ? ? ? ? ? ? ? ? ? ? ? 那么就可以得到以下的結(jié)果:[<p class = "story">....</p>]

????????????????????????????在這個(gè)例子中p:nth-of-type(3)這條語(yǔ)法相當(dāng)于是選擇第三個(gè)p標(biāo)簽蹂随,相當(dāng)于soup.select(p)[2])

? ? ? ? ? ? ? ? 我們也可以通過(guò)tag逐層尋找:

????????????????????????????soup.select("body a")這方法可以找到body下所有的a標(biāo)簽

? ? ? ? ? ? ? ? ? ? ? ? ? ? 也可以用這個(gè)soup.select("body > a")(這里的body和>和a之間一定要有空格)這個(gè)方法的話可以得到的是body下屬的第一個(gè)a標(biāo)簽

? ? ? ? ? ? ? ? 也可以來(lái)組合一下:

? ? ? ? ? ? ? ? ????????????soup.select("p > a:nth-of-type(2)")

? ? ? ? ? ? ? ? 當(dāng)然也會(huì)有尋找兄弟節(jié)點(diǎn)的方法:

? ? ? ? ? ? ? ? ? ? ? ? ? ? soup.select("#link1 ~ .mysis")這個(gè)方法可以找到id = link1后的所有兄弟節(jié)點(diǎn)標(biāo)簽

? ? ? ? ? ? ? ? ? ? ? ? ? ? 而這個(gè)方法soup.select("#link1 + .mysis")是可以得到id = link1的下一個(gè)兄弟標(biāo)簽

2.我們也可以通過(guò)類(lèi)名來(lái)尋找

? ? ? ? ? ? ? ? 例如:

????????????????????????????soup.select(".story")這個(gè)方法可以找到所有class為story的標(biāo)簽

? ??????????????????????????soup.select("p.sister")這個(gè)方法可以找到所有class為story的p標(biāo)簽

3.也可以通過(guò)id去查找

? ? ? ? ? ? ? ? 例如:

? ??????????????????????????soup.select("#link1")這個(gè)方法可以找到所有id = #link的標(biāo)簽

? ??????????????????????????soup.select("a#link2")而這個(gè)方法可以得到所有id = #link的a標(biāo)簽

4.也可以通過(guò)屬性來(lái)查找

? ? ? ? ? ? ? ? ? ? ? ? ? ? 一、是否存在某種屬性:

????????????????????????????????????????soup.select('a[href]')尋找存在href屬性的標(biāo)簽

? ? ? ? ? ? ? ? ? ? ? ? ? ? 二因惭、通過(guò)屬性的值去尋找:

? ??????????????????????????????????????soup.select('a[)這條指令可以找到所有href值為http://example.com/elsie的a標(biāo)簽

5.也可以通過(guò)語(yǔ)言來(lái)設(shè)置:

????????????????????????????看這個(gè)例子:

language = """

<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>

"""

soup = BeautifulSoup(language,'lxml')

soup.select('p[lang|=en]')這條指令可以得到一下結(jié)果:[<p lang= "en">Hello</p>,<p lang="en-us">Howdy,y'all</p>,<p lang="en-gb">Pip-pip, old fruit</p>]

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末岳锁,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子筛欢,更是在濱河造成了極大的恐慌浸锨,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,122評(píng)論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件版姑,死亡現(xiàn)場(chǎng)離奇詭異柱搜,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)剥险,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,070評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén)聪蘸,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人表制,你說(shuō)我怎么就攤上這事健爬。” “怎么了么介?”我有些...
    開(kāi)封第一講書(shū)人閱讀 164,491評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵娜遵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我壤短,道長(zhǎng)设拟,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,636評(píng)論 1 293
  • 正文 為了忘掉前任久脯,我火速辦了婚禮纳胧,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘帘撰。我一直安慰自己跑慕,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,676評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布摧找。 她就那樣靜靜地躺著核行,像睡著了一般。 火紅的嫁衣襯著肌膚如雪蹬耘。 梳的紋絲不亂的頭發(fā)上钮科,一...
    開(kāi)封第一講書(shū)人閱讀 51,541評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音婆赠,去河邊找鬼绵脯。 笑死佳励,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的蛆挫。 我是一名探鬼主播赃承,決...
    沈念sama閱讀 40,292評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼悴侵!你這毒婦竟也來(lái)了瞧剖?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,211評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤可免,失蹤者是張志新(化名)和其女友劉穎抓于,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體浇借,經(jīng)...
    沈念sama閱讀 45,655評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡捉撮,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,846評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了妇垢。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片巾遭。...
    茶點(diǎn)故事閱讀 39,965評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖闯估,靈堂內(nèi)的尸體忽然破棺而出灼舍,到底是詐尸還是另有隱情,我是刑警寧澤涨薪,帶...
    沈念sama閱讀 35,684評(píng)論 5 347
  • 正文 年R本政府宣布骑素,位于F島的核電站,受9級(jí)特大地震影響刚夺,放射性物質(zhì)發(fā)生泄漏献丑。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,295評(píng)論 3 329
  • 文/蒙蒙 一光督、第九天 我趴在偏房一處隱蔽的房頂上張望阳距。 院中可真熱鬧塔粒,春花似錦结借、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,894評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至圃酵,卻和暖如春柳畔,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背郭赐。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,012評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工薪韩, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,126評(píng)論 3 370
  • 正文 我出身青樓俘陷,卻偏偏與公主長(zhǎng)得像罗捎,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子拉盾,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,914評(píng)論 2 355

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