1、介紹css
Beautiful Soup是一個能夠從HTML或XML文件中提取數據的python庫。html
#安裝Beautiful Soup pip install beautifulsoup4 #安裝解析器 Beatiful Soup支持python標準庫中的HTML解析器,還支持一些第三方的解析器,其中一個是lxml,安裝lxml: pip install lxml #這個使用率最高的 另一個可供選擇的解析器是純python實現的html5lib,html5lib的解析方式與瀏覽器相同,安裝方式: pip install html5lib
下表列出了主要的解析器,以及它們的優缺點,官網推薦使用lxml做爲解析器,由於效率更高. 在Python2.7.3以前的版本和Python3中3.2.2以前的版本,必須安裝lxml或html5lib, 由於那些Python版本的標準庫中內置的HTML解析方法不夠穩定.html5
解析器 | 使用方法 | 優點 | 劣勢 |
---|---|---|---|
Python標準庫 | BeautifulSoup(markup, "html.parser") |
|
|
lxml HTML 解析器 | BeautifulSoup(markup, "lxml") |
|
|
lxml XML 解析器 | BeautifulSoup(markup, ["lxml", "xml"])python BeautifulSoup(markup, "xml")瀏覽器 |
|
|
html5lib | BeautifulSoup(markup, "html5lib") |
|
|
2、基本使用app
html_doc = """ <html><head><title>The Dormouse's story</title></head> <body> <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 href="http://example.com/elsie" class="sister" id="link1">Elsie</a>, <a href="http://example.com/lacie" class="sister" id="link2">Lacie</a> and <a href="http://example.com/tillie" class="sister" id="link3">Tillie</a>; and they lived at the bottom of a well.</p> <p class="story">...</p> """ #基本使用:容錯處理,文檔的容錯能力指的是在html代碼不完整的狀況下,使用該模塊能夠識別該錯誤。使用BeautifulSoup解析上述代碼,可以獲得一個 BeautifulSoup 的對象,並能按照標準的縮進格式的結構輸出 from bs4 import BeautifulSoup soup=BeautifulSoup(html_doc,'lxml') #具備容錯功能 res=soup.prettify() #處理好縮進,結構化顯示 print(res)
3、遍歷文檔樹spa
遍歷文檔樹:即直接經過標籤名字選擇,特色是選擇速度快,但若是存在多個相同的標籤只返回第一個code
html_doc = """ <html><head><title>The Dormouse's story</title></head> <body> <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 href="http://example.com/elsie" class="sister" id="link1">Elsie</a>, <a href="http://example.com/lacie" class="sister" id="link2">Lacie</a> and <a href="http://example.com/tillie" class="sister" id="link3">Tillie</a>; and they lived at the bottom of a well.</p> <p class="story">...</p> """ from bs4 import BeautifulSoup soup=BeautifulSoup(html_doc,'lxml') #具備容錯功能 res=soup.prettify() #處理好縮進,結構化顯示 #1.用法 print(soup.p) #存在多個相同的標籤只取出第一個p標籤 #<p class="title"><b>The Dormouse's story</b></p> #2.獲取標籤的名稱 print(soup.p.name) #p #3.獲取標籤的屬性 print(soup.p.attrs) #{'class': ['title']} 以字典形式打印 #4.獲取標籤的內容 print(soup.p.string) #The Dormouse's story #p下的文本只有一個時才能取到,不然爲None print(soup.p.strings) #拿到的是生成器對象,取到p下全部的文本內容 print(soup.p.text) #取到p下全部的文本內容 for line in soup.stripped_strings: #去掉空白 print(line)
#5.子節點、子孫節點 print(soup.p.contents) #p下全部子節點 #[<b>The Dormouse's story</b>] print(soup.p.children) #獲得一個迭代器,包含p下全部的子節點 <list_iterator object at 0x00000054B207C780> for i,child in enumerate(soup.p.children): #循環取出 print(i,child) #0 <b>The Dormouse's story</b> print(soup.p.descendants) #獲取p下面全部的子孫節點 <generator object descendants at 0x00000054B203C258> for i,child in enumerate(soup.p.descendants): #文本也會顯示出來 print(i,child) #0 <b>The Dormouse's story</b> 1 The Dormouse's story #6.父節點、祖先節點 print(soup.a.parent) #獲取a標籤的父節點 print(soup.a.parents) #找到a標籤全部的祖父節點,父親的父親。。。
4、搜索文檔樹orm
1.五種過濾器xml
搜索文檔樹:Beautiful Soup定義了不少搜索方法,這裏着重介紹2個:find()和find_all()
html_doc = """ <html><head><title>The Dormouse's story</title></head> <body> <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 href="http://example.com/elsie" class="sister" id="link1">Elsie</a>, <a href="http://example.com/lacie" class="sister" id="link2">Lacie</a> and <a href="http://example.com/tillie" class="sister" id="link3">Tillie</a>; and they lived at the bottom of a well.</p> <p class="story">...</p> """ from bs4 import BeautifulSoup soup=BeautifulSoup(html_doc,'lxml') res=soup.prettify() #處理好縮進,結構化顯示 #1.五種過濾器:字符串、正則、列表、True、方法 #1.1 字符串:即標籤名 print(soup.find_all('a')) #寫標籤名,find_all找出全部a標籤 [<a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>, <a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>, <a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>] #1.2 正則 import re print(soup.find_all(re.compile('^b'))) #找到b開頭的標籤,結果有body和b標籤 #1.3列表:若是傳入列表參數,Beautiful Soup會將與列表中任一元素匹配的結果返回 print(soup.find_all(['a',['b']])) #包含a和b標籤 [<b>The Dormouse's story</b>, <a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>, <a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>, <a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>] #1.4 True:能夠匹配任何值,下面代碼查到全部的tag,可是不會返回字符串節點 print(soup.find_all(True)) #返回全部標籤 for tag in soup.find_all(True): print(tag.name) #返回全部節點:html/p/a/head... #1.5方法:若是沒有合適的過濾器,能夠自定義一個方法,方法接受一個元素參數,若是方法返回True表示當前元素匹配成功,若是沒找到返回False def has_class_but_no_id(tag): return tag.has_attr('class') and not tag.attr('id') print(soup.find_all(has_class_but_no_id))
2.find_all(name,attrs,recursive,text,**kwargs) 查詢全部
#2.1 name:搜索name參數的值能夠是任一類型的過濾器:字符串、正則、列表、True、方法 import re print(soup.find_all(name=re.compile('^b'))) #這裏加不加name均可以 #2.2 keyword: key=value的形式,value能夠是過濾器:字符串、正則、列表、True print(soup.find_all(class_=re.compile('title'))) #[<p class="title"><b>The Dormouse's story</b></p>] 匹配class是title的標籤,注意類用class_ print(soup.find_all(id=True)) #查找有id屬性的標籤 #2.3按照類名查找,注意關鍵字是class_,class_=value,value能夠是五種選擇器之一 print(soup.find_all('a',class_='sister')) #查找類爲sister的a標籤 print(soup.find_all('a',class_='sister sss')) #查找類爲sister和sss的a標籤 #2.4 attrs print(soup.find_all('p',attrs={'class':'story'})) #查找class=story的p標籤 #2.5 text 值能夠是:字符串,列表,True,正則 print(soup.find_all(text='Elsie')) #Elsie 文本 print(soup.find_all('a',text='Elsie')) #獲取Elsie文本的a標籤 #2.6 limit參數:限制取值個數 print(soup.find_all('a',limit=2)) #取兩條a標籤 #2.7 recursive: print(soup.find_all('a')) #取出a標籤的 print(soup.find_all('a',recursive=False)) #取出a標籤的子節點 []
3.find(name,attrs,recursive,text,**kwargs) 查詢第一個符合條件的標籤
#3.find(name,attrs,recursive,text,**kwargs) find_all() 方法將返回文檔中符合條件的全部tag,儘管有時候咱們只想獲得一個結果。好比文檔中只有一個a標籤,那麼能夠直接使用find()方法來查找。 惟一區別就是find_all()查詢到的結果返回的是包含元素的列表,而find()方法直接返回結果。 find_all()沒有找到符合元素返回空列表,find()方法找不到目標時返回None.
4.css選擇器 (******)使用select獲取
#使用select方法來查詢 #1.css選擇器 print(soup.select('.sister')) #查詢class=sister的標籤 print(soup.select('#link1')) print(soup.select('#link1')[0]) print(soup.select('#link1')[0].text) #只要下面能夠取值就能夠一直. 下去 #2.獲取屬性 print(soup.select('#link2')[0].attrs) #{'href': 'http://example.com/lacie', 'class': ['sister'], 'id': 'link2'} #3.獲取內容 print(soup.select('#link1')[0].get_text())或者 print(soup.select('#link1')[0].text)
總結:
1.推薦使用lxml解析庫 2.講了三種選擇器:標籤選擇器,find和find_all,css選擇器 1.標籤選擇器篩選功能弱,可是速度快 2.建議使用find,find_all查詢匹配單個結果或者多個結果 3.若是對css選擇器很是熟悉建議使用select 3.獲取屬性attrs和獲取文本get_text()方法