Python爬蟲系列(六):搜索文檔樹

今天早上倔既,寫的東西掉了恕曲。這個爛知乎,有bug渤涌,說了自動保存草稿佩谣,其實并沒有保存。無語

今晚实蓬,我們將繼續(xù)討論如何分析html文檔茸俭。

1.字符串

#直接找元素

soup.find_all('b')

2.正則表達式

#通過正則找

import re

for tag in soup.find_all(re.compile("^b")):

print(tag.name)

3.列表

找a 和 b標簽

soup.find_all(["a", "b"])

4.True

找所有標簽

fortaginsoup.find_all(True):

print(tag.name)

5.方法

defhas_class_but_no_id(tag):

returntag.has_attr('class')andnottag.has_attr('id')

#調用外部方法。只返回方法滿足為true的元素

soup.find_all(has_class_but_no_id)

6.find_all

ind_all() 方法搜索當前tag的所有tag子節(jié)點,并判斷是否符合過濾器的條件.這里有幾個例子:

soup.find_all("title")

#找class=title的p元素

soup.find_all("p", "title")

#找所有元素

soup.find_all("a")

#通過ID找

soup.find_all(id="link2")

#通過內容找

importre

soup.find(text=re.compile("sisters"))

#通過正則:查找元素屬性滿足條件的

soup.find_all(href=re.compile("elsie"))

#查找包含id的元素

soup.find_all(id=True)

#多條件查找

soup.find_all(href=re.compile("elsie"), id='link1')

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

data_soup = BeautifulSoup('

foo!
')

data_soup.find_all(data-foo="value")

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

data_soup.find_all(attrs={"data-foo": "value"})

#按CSS搜索 注意class的用法

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

soup.find_all("a", class_="sister")

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

soup.find_all(class_=re.compile("itl"))

defhas_six_characters(css_class):

returncss_classisnotNoneandlen(css_class) == 6

soup.find_all(class_=has_six_characters)

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

css_soup = BeautifulSoup('')

css_soup.find_all("p", class_="strikeout")

css_soup.find_all("p", class_="body")

搜索 class 屬性時也可以通過CSS值完全匹配

css_soup.find_all("p", class_="body strikeout")

完全匹配 class 的值時,如果CSS類名的順序與實際不符,將搜索不到結果

soup.find_all("a", attrs={"class": "sister"})

通過 text 參數可以搜搜文檔中的字符串內容.

與 name 參數的可選值一樣, text 參數接受 字符串 , 正則表達式 , 列表, True .

soup.find_all(text="Elsie")

soup.find_all(text=["Tillie", "Elsie", "Lacie"])

soup.find_all(text=re.compile("Dormouse"))

def is_the_only_string_within_a_tag(s):

return (s == s.parent.string)

soup.find_all(text=is_the_only_string_within_a_tag)

雖然 text 參數用于搜索字符串,還可以與其它參數混合使用來過濾tag.Beautiful Soup會找到 .string 方法與 text 參數值相符的tag.下面代碼用來搜索內容里面包含“Elsie”的標簽

soup.find_all("a", text="Elsie")

find_all() 方法返回全部的搜索結構,如果文檔樹很大那么搜索會很慢.如果我們不需要全部結果,可以使用 limit 參數限制返回結果的數量.效果與SQL中的limit關鍵字類似,當搜索到的結果數量達到 limit 的限制時,就停止搜索返回結果

soup.find_all("a", limit=2)

調用tag的 find_all() 方法時,Beautiful Soup會檢索當前tag的所有子孫節(jié)點,如果只想搜索tag的直接子節(jié)點,可以使用參數 recursive=False .

soup.html.find_all("title")

soup.html.find_all("title", recursive=False)

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

soup.find_all("a")

soup("a")

soup.title.find_all(text=True)

soup.title(text=True)

7.find

soup.find_all('title', limit=1)與soup.find('title')一樣

find就是找到滿足條件的第一個就返回安皱。all返回列表调鬓,find返回一個對象

find_all() 方法沒有找到目標是返回空列表, find() 方法找不到目標時,返回 None

soup.head.title 是 tag的名字 方法的簡寫.這個簡寫的原理就是多次調用當前tag的 find() 方法

soup.head.title與soup.find("head").find("title")

8.find_parents() 和 find_parent()

soup = BeautifulSoup(html_doc, "lxml")

a_string = soup.find(text="Lacie")

print('1---------------------------')

print(a_string)

print('2---------------------------')

#找直接父節(jié)點

print(a_string.find_parents("a"))

print('3---------------------------')

#迭代找父節(jié)點

print(a_string.find_parent("p"))

print('4---------------------------')

#找直接父節(jié)點

print(a_string.find_parents("p", class_="title"))

9.find_next_siblings() 合 find_next_sibling()

soup = BeautifulSoup(html_doc, "lxml")

a_string = soup.find(text="Lacie")

print('1---------------------------')

first_link = soup.a

print(first_link)

print('2---------------------------')

#找當前元素的所有后續(xù)元素

print(first_link.find_next_siblings("a"))

print('3---------------------------')

first_story_paragraph = soup.find("p", "story")

#找當前元素的緊接著的第一個元素

print(first_story_paragraph.find_next_sibling("p"))

10.find_previous_siblings() 和 find_previous_sibling()

和第9點方向相反

last_link = soup.find("a", id="link3")

last_link

last_link.find_previous_siblings("a")

first_story_paragraph = soup.find("p", "story")

first_story_paragraph.find_previous_sibling("p")

11.find_all_next() 和 find_next()

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

first_link.find_all_next(text=True)

first_link.find_next("p")

12.find_all_previous() 和 find_previous()

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

first_link.find_all_previous("p")

first_link.find_previous("title")

13.CSS選擇器

查找class=title的元素

soup.select("title")

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

通過元素層級查找

soup.select("body a")

soup.select("html head title")

找直接子元素

soup.select("head > title")

soup.select("p > a")

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

oup.select("p > #link1")

up.select("body > a")

找到兄弟節(jié)點標簽

soup.select("#link1 ~ .sister")

soup.select("#link1 + .sister")

通過CSS的類名查找

soup.select(".sister")

這里的class沒有加 _

soup.select("[class~=sister]")

通過tag的id查找

soup.select("#link1")

通過是否存在某個屬性來查找

oup.select('a[href]')

通過屬性的值來查找

soup.select('a[)

通過語言設置來查找:就是通過元素屬性來查找


multilingual_soup = BeautifulSoup(multilingual_markup)

multilingual_soup.select('p[lang|=en]')

這一部分內容,了解jquery的人一眼就看明白了

作為程序員练俐,一定要學會觸類旁通

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末袖迎,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子腺晾,更是在濱河造成了極大的恐慌燕锥,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,839評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件悯蝉,死亡現(xiàn)場離奇詭異归形,居然都是意外死亡,警方通過查閱死者的電腦和手機鼻由,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,543評論 2 382
  • 文/潘曉璐 我一進店門暇榴,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人蕉世,你說我怎么就攤上這事蔼紧。” “怎么了狠轻?”我有些...
    開封第一講書人閱讀 153,116評論 0 344
  • 文/不壞的土叔 我叫張陵奸例,是天一觀的道長。 經常有香客問我向楼,道長查吊,這世上最難降的妖魔是什么谐区? 我笑而不...
    開封第一講書人閱讀 55,371評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮逻卖,結果婚禮上宋列,老公的妹妹穿的比我還像新娘。我一直安慰自己评也,他們只是感情好炼杖,可當我...
    茶點故事閱讀 64,384評論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著仇参,像睡著了一般嘹叫。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上诈乒,一...
    開封第一講書人閱讀 49,111評論 1 285
  • 那天罩扇,我揣著相機與錄音,去河邊找鬼怕磨。 笑死喂饥,一個胖子當著我的面吹牛,可吹牛的內容都是我干的肠鲫。 我是一名探鬼主播员帮,決...
    沈念sama閱讀 38,416評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼导饲!你這毒婦竟也來了捞高?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 37,053評論 0 259
  • 序言:老撾萬榮一對情侶失蹤渣锦,失蹤者是張志新(化名)和其女友劉穎硝岗,沒想到半個月后,有當地人在樹林里發(fā)現(xiàn)了一具尸體袋毙,經...
    沈念sama閱讀 43,558評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡型檀,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,007評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了听盖。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片胀溺。...
    茶點故事閱讀 38,117評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖皆看,靈堂內的尸體忽然破棺而出仓坞,到底是詐尸還是另有隱情,我是刑警寧澤腰吟,帶...
    沈念sama閱讀 33,756評論 4 324
  • 正文 年R本政府宣布扯躺,位于F島的核電站,受9級特大地震影響蝎困,放射性物質發(fā)生泄漏录语。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,324評論 3 307
  • 文/蒙蒙 一禾乘、第九天 我趴在偏房一處隱蔽的房頂上張望澎埠。 院中可真熱鬧,春花似錦始藕、人聲如沸蒲稳。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,315評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽江耀。三九已至,卻和暖如春诉植,著一層夾襖步出監(jiān)牢的瞬間祥国,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,539評論 1 262
  • 我被黑心中介騙來泰國打工晾腔, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留舌稀,地道東北人。 一個月前我還...
    沈念sama閱讀 45,578評論 2 355
  • 正文 我出身青樓灼擂,卻偏偏與公主長得像壁查,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子剔应,可洞房花燭夜當晚...
    茶點故事閱讀 42,877評論 2 345

推薦閱讀更多精彩內容