BeautifulSoup

Beautiful Soup提供一些簡單的、python式的函數用來處理導航、搜索、修改分析樹等功能。
它是一個工具箱,經過解析文檔爲用戶提供須要抓取的數據,由於簡單,因此不須要多少代碼就能夠寫出一個完整的應用程序。html

 

1、安裝python

pip install beautifulsoup4
pip install lxml

 

2、使用正則表達式

from bs4 import BeautifulSoup soup = BeautifulSoup(html_doc,'lxml') res = soup.prettify()   # 結構化顯示,並補全標籤

 

3、遍歷文檔樹函數

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 class="sister" href="http://example.com/elsie" id="link1"> Elsie </a> , <a class="sister" href="http://example.com/lacie" id="link2"> Lacie </a> and <a class="sister" href="http://example.com/tillie" id="link3"> Tillie </a> ; and they lived at the bottom of a well. </p> <p class="story"> ... </p> </body> </html> """

 

from bs4 import BeautifulSoup soup = BeautifulSoup(html_doc,'lxml') print(soup.p)             # 找到第一個P標籤
print(soup.p.name)        # 獲取標籤的名稱 p
print(soup.p.attrs)       # 獲取標籤的屬性 {'class': ['title']}

 

獲取標籤的文本工具

print(soup.p.text)        # 獲取p標籤下的全部內容
print(soup.p.get_text())  # 獲取p標籤下的全部內容
print(soup.p.string)      # p標籤的文本只有一個時,不然返回None
print(soup.p.strings)     # 獲取生成器對象,取到P標籤下的全部內容

for line in soup.p.strings: print(line)

 

tag對象spa

tag_p = soup.p print(tag_p.attrs)              # {'class': ['title'], 'id': 'p1'}
print(tag_p['class'])           # ['title']
print(tag_p.get('class'))       # ['title']
print(tag_p['id'])              # p1
print(tag_p.get('id'))          # p1

 

#一、嵌套選擇
print(soup.head.title.string) print(soup.body.a.string) #二、子節點、子孫節點
print(soup.p.contents) #p下全部子節點
print(soup.p.children) #獲得一個迭代器,包含p下全部子節點

for i,child in enumerate(soup.p.children): print(i,child) print(soup.p.descendants) #獲取子孫節點,p下全部的標籤都會選擇出來
for i,child in enumerate(soup.p.descendants): print(i,child) #三、父節點、祖先節點
print(soup.a.parent) #獲取a標籤的父節點
print(soup.a.parents) #找到a標籤全部的祖先節點,父親的父親,父親的父親的父親...


#四、兄弟節點
print(soup.a.next_sibling) #下一個兄弟
print(soup.a.previous_sibling) #上一個兄弟

print(list(soup.a.next_siblings)) #下面的兄弟們=>生成器對象
print(soup.a.previous_siblings) #上面的兄弟們=>生成器對象

 

4、五種過濾器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="title"><b>$75</b></p> <p id="meiyuan">啦啦啦啦啦啦</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>'''
from bs4 import BeautifulSoup soup = BeautifulSoup(html_doc,'lxml') # find_all(self, name=None, attrs={}, recursive=True, text=None, limit=None, **kwargs)

# 1.字符串,即標籤名,特色時徹底匹配
print(soup.find_all('b'))      # 找到全部的p標籤,返回列表
print(soup.find_all(attrs={'class':"sister"}))  # 找到class屬性是sister的標籤

# 2.正則表達式
import re print(soup.find_all(re.compile('^h')))  # 找到全部h開頭的標籤,head和html標籤
print(soup.find_all(attrs={"id":re.compile("link")}))       # 找到id有link的標籤

# 3.列表
print(soup.find_all(['a','b']))           # 找到全部的a標籤和b標籤


# 4.True:能夠匹配任何值,下面代碼查找到全部的tag,可是不會返回字符串節點
print(soup.find_all(attrs={"id":True}))     # 查找全部含有id的標籤
print(soup.find_all(name=True))               # 找到全部標籤的標籤名

# 5.方法:若是沒有合適過濾器,那麼還能夠定義一個方法,方法只接受一個元素參數 ,若是這個方法返回 True 表示當前元素匹配而且被找到,若是不是則反回 False

def has_class_not_id(tag): # 有class屬性沒id的標籤
    return tag.has_attr("class") and not tag.has_attr("id") print(soup.find_all(has_class_not_id)) print(soup.find_all(name="a",limit=2))#找全部的a標籤,只找前兩個
print(soup.body.find_all(attrs={"class":"sister"},recursive=False))#找屬性爲sister的
print(soup.html.find_all('a')) print(soup.html.find_all('a',recursive=False)) # recursive = True #從子子孫孫都找到了 # recursive = False #若是隻想搜索tag的直接子節點(就不往裏面找了),可使用參數 recursive=False .

# **kwargs
print(soup.find_all(attrs={"class":"sister"})) print(soup.find_all(class_="sister"))  #這兩個是同樣的

print(soup.find_all(attrs={"id":"link3"})) #這兩個是同樣的,只是表示方式不同
print(soup.find_all(id="link3"))

 

find_all() 和 find() 的區別orm

惟一的區別是 find_all() 方法的返回結果是值包含一個元素的列表,而 find() 方法直接返回結果.
find_all() 方法沒有找到目標是返回空列表, find() 方法找不到目標時,返回 None .xml

find_all( name , attrs , recursive , text , **kwargs )
find( name , attrs , recursive , text , **kwargs )htm

像調用 find_all() 同樣調用tag find_all() 幾乎是Beautiful Soup中最經常使用的搜索方法,因此咱們定義了它的簡寫方法. BeautifulSoup 對象和 tag 對象能夠被看成一個方法來使用, 這個方法的執行結果與調用這個對象的 find_all() 方法相同,下面兩行代碼是等價的: soup.find_all("a") soup("a") 這兩行代碼也是等價的: soup.title.find_all(text=True) soup.title(text=True)

 

CSS選擇器

html_doc = """ <html><head><title>The Dormouse's story</title></head> <body> <p class="title"> <b>The Dormouse's story</b> Once upon a time there were three little sisters; and their names were <a href="http://example.com/elsie" class="sister" id="link1"> <span>Elsie</span> </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>; <div class='panel-1'> <ul class='list' id='list-1'> <li class='element'>Foo</li> <li class='element'>Bar</li> <li class='element'>Jay</li> </ul> <ul class='list list-small' id='list-2'> <li class='element'><h1 class='yyyy'>Foo</h1></li> <li class='element xxx'>Bar</li> <li class='element'>Jay</li> </ul> </div> and they lived at the bottom of a well. </p> <p class="story">...</p> """

from bs4 import BeautifulSoup soup=BeautifulSoup(html_doc,'lxml') # 1.經過標籤名查找
print(soup.select("title"))     # 返回title標籤的列表

# 2.經過類名查找
print(soup.select(".sister")) # 3.經過ID查找
print(soup.select("#link1")) # 獲取屬性
print(soup.select("#list-2")[0].attrs)  # {'class': ['list', 'list-small'], 'id': 'list-2'}

# 獲取內容
print(soup.select("#list-2")[0].text)
相關文章
相關標籤/搜索