今天早上倔既,寫的東西掉了恕曲。這個爛知乎,有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('
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的人一眼就看明白了
作為程序員练俐,一定要學會觸類旁通