目錄
頁面解析和數據提取
一般來講對我們而言,需要抓取的是某個網站或者某個應用的內容,提取有用的價值。內容一般分爲兩部分,非結構化的數據和 結構化的數據。
- 非結構化數據:先有數據,再有結構,
- 結構化數據:先有結構、再有數據
不同類型的數據,我需要採用不同的方式來處理。
- 非結構化的數據處理
- 文本、電話號碼、郵箱地址:
- 正則表達式
- html文件:
- 正則表達式
- xpath
- css選擇器
- bs4
- 文本、電話號碼、郵箱地址:
- 結構化的數據處理
- json文件:
- jsonPath
- 轉化成Python類型進行操作(json類)
- xml文件:
- 轉化成Python類型(xmltodict)
- XPath
- CSS選擇器
- 正則表達式
- json文件:
Beautiful Soup 4.2.0 文檔
更爲詳細內容,可參考官方文檔,URL:http://beautifulsoup.readthedocs.io/zh_CN/latest/
一、簡介
官方文檔:http://beautifulsoup.readthedocs.io/zh_CN/v4.4.0
https://www.crummy.com/software/BeautifulSoup/bs4/doc/index.zh.html
Beautiful Soup是一個HTML / XML的解析器,主要的功能是解析和提取HTML / XML數據。
lxml只會局部遍歷,而Beautiful Soup是基於HTML DOM的,會載入整個文檔,解析整個DOM樹,因此時間和內存開銷都會大很多,所以性能要低於lxml。
BeautifulSoup用來解析HTML比較簡單,API非常人性化,支持CSS選擇器,Python標準庫中的HTML解析器,也支持lxml的XML解析器。
Beautiful Soup 3目前已經停止開發,推薦現在的項目使用Beautiful Soup 4.使用pip安裝即可:
pip install beautifulsoup4
抓取工具 | 速度 | 使用難度 | 安裝難度 |
---|---|---|---|
正則 | 最快 | 困難 | 無(內置) |
BeautifulSoup | 慢 | 最簡單 | 簡單 |
LXML | 快 | 簡單 | 一般 |
二、bs4的使用
1、導入模塊
#安裝 Beautiful Soup
pip install html5lib
#安裝解析器
pip install lxml
2、獲取節點
from bs4 import BeautifulSoup
html_doc = """
<html><head><title>The Dormouse's story</title></head>
<body>
<p class="title title1">
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
<em>hello</em>
<b>The Dormouse's story</b>
<i>haskdjfhakjsf</i>
</p>
<p class="story" id='story'>
<i>
<a href="http://example.com/elsie" class="sister" id="link1">Elsie</a>
<a href="http://example.com/lacie" class="sister" id="link2">Lacie</a>
<a href="http://example.com/tillie" class="sister" id="link3">Tillie</a>
</i>
</p>
<p class="story">...</p>
"""
# 用lxml格式解析html 解析器
# soup = BeautifulSoup(html_doc,"lxml")
soup = BeautifulSoup(html_doc,"html5lib")
# print(soup)
# print(type(soup))
# 格式化
# print(soup.prettify())
# 標籤選擇
print('soup.title 輸出:',soup.title)
# 打印第一個
print('soup.p 輸出:',soup.p)
# 獲取文本內容
#get_text() 獲取當前標籤下,子孫標籤的所有文本
print('soup.i.get_text() 輸出:',soup.i.get_text())
# string只能獲取當前標籤下的文本
print('soup.i.string 輸出:',soup.i.string)
print('soup.i.text 輸出:',soup.i.text)
# 標籤屬性
print('soup.title.name 輸出:',soup.title.name)
# attrs所有的屬性,字典字典{"屬性名":[值]}
print('soup.p.attrs 輸出:',soup.p.attrs)
# 訪問屬性
print("soup.p.attrs['class'] 輸出:",soup.p.attrs['class'])
# 直接訪問屬性
print("soup.p['class'] 輸出:",soup.p['class'])
# 獲取父節點
print("soup.p.parent 輸出:",soup.p.parent)
# 獲取祖父節點
# print("soup.p.parents 輸出:",soup.p.parents)
3、尋找節點
3.1 通過find()來查找
#只找第一個
# find
# name=None, 便籤名
#attrs={} ,屬性名
# 只找第一個標籤
print(soup.find('p'))
# 通過類名來查找節點
print(soup.find('p',attrs={'class':"story"}))
print(soup.find('p',class_="story"))
# 通過id來查找節點
print(soup.find('p',id="story"))
3.2通過find_all()來查找
#查找全部
# find_all
'''
參數:name=None, attrs={}, recursive=True,
text=None,limit=None, **kwargs
'''
# 查找所有符合的標籤,返回一個列表
print(soup.find_all('p'))
# 限制輸出
print(soup.find_all('a',limit=2))
# 使用正則
print(soup.find_all(re.compile('^p')))
print(soup.find_all(text=re.compile("^L")))
3.3 通過select()來查找
# css選擇器
# 查找id爲story下的a(子孫節點)
print(soup.select("#story a"))
# 查找id爲story下的子節點下的a(子節點)
print(soup.select("#story > i > a"))