Beautiful Soup庫安裝
pip install beautifulsoup4
測試:
import requests r = requests.get("http://Python123.io/ws/demo.html") demo = r.text form bs4 import BeautifulSoup #從bs4中引入BeautifulSoup類 soup = BeautifulSoup(demo, "html.parser")
Beautiful Soup庫是解析、遍歷、維護“標簽樹”的功能庫
Beautiful Soup庫的基本元素
Beautiful Soup庫的引用
Beautiful Soup庫,也叫beautifulsoup4或bs4.
from bs4 import BeautifulSoup soup = BeautifulSoup(demo,"html.parser")
Beautiful Soup類的基本元素
基于bs4庫的HTML內容遍歷方法
下行遍歷
#遍歷兒子節點 for child in soup.body.children print(child) #遍歷子孫節點 for child in soup.body.descendants print(child)
上行遍歷
soup = BeautifulSoup(demo,"html.parser") for parent in soup.a.parents: if parent is None: print(parent) else: print(parent.name) #輸出結果 #p #body #html #[document]
平行遍歷
平行遍歷發生在同一個父節點下的各節點間。
下一個獲取的可能是字符串類型,不一定是下一個節點。
#遍歷后續節點 for sibling in soup.a.next_siblings print(sibling) #遍歷前續節點 for sibling in soup.a.previous_siblings print(sibling)
基于bs4庫的HTML格式化和編碼
格式化方法:.prettify()
soup = BeautifulSoup(demo,"html.parser") print(soup.a.prettify())
編碼:默認utf-8
soup = BeautifulSoup("<p>中文</p>","html.parser") soup.p.string #'中文' print(soup.p.prettify()) #<p> # 中文 #</p>
3.信息組織與提取
信息標記的三種形式
標記后的信息可形成信息組織結構,增加了信息的維度;
標記后的信息可用于通信、存儲和展示;
標記的結構和信息一樣具有重要價值;
標記后的信息有利于程序的理解和運用。
XML: eXtensible Matkup Language
最早的通用信息標記語言,可擴展性好,但繁瑣。
用于Internet上的信息交互和傳遞。
<name>...</name> <name/> <!-- -->
JSON: JAVAScript Object Notation
信息有類型,適合程序處理(js),較XML簡潔。
用于移動應用云端和節點的信息通信,無注釋。
#有類型的鍵值對表示信息的標記形式 "key":"value" "key":["value1","value2"] "key":{"subkey":"subvalue"}
YAMl: YAML Ain’t Markup Language
信息無類型,文本信息比例最高,可讀性好。
用于各類系統的配置文件,有注釋易讀。
#無類型的鍵值對表示信息的標記形式 key : "value" key : #comment -value1 -value2 key : subkey : subvalue
信息提取的一般方法
方法一:完整解析信息的標記形式,再提取關鍵信息。
XML JSON YAML
需要標記解析器,例如bs4庫的標簽樹遍歷。
優點:信息解析準確
缺點:提取過程繁瑣,過程慢
方法二:無視標記形式,直接搜索關鍵信息
搜索
對信息的文本查找函數即可。
優點:提取過程簡潔,速度較快
缺點:提取過程準確性與信息內容相關
融合方法:結合形式解析與搜索方法,提取關鍵信息
XML JSON YAML 搜索
需要標記解析器及文本查找函數。
實例:提取HTML中所有URL鏈接
思路:
1、搜索到所有 標簽
2、解析 標簽格式,提取href后的鏈接內容
form bs4 import BeautifulSoup soup = BeautifulSoup(demo,"html.parser") for link in soup.find_all('a'): print(link.get('href'))
基于bs4庫的HTML內容查找方法
簡寫形式:
(…) 等價于
.find_all(…)
#name:對標簽名稱的檢索字符串 soup.find_all('a') soup.find_all(['a', 'b']) soup.find_all(True) #返回soup的所有標簽信息 for tag in soup.find_all(True): print(tag.name) #html head title body p b p a a #輸出所有b開頭的標簽,包括b和body #引入正則表達式庫 import re for tag in soup.find_all(re.compile('b')): print(tag.name) #body b #attrs:對標簽屬性值的檢索字符串,可標注屬性檢索 soup.find_all('p', 'course') soup.find_all(id='link1') import re soup.find_all(id=re.compile('link')) #recursive:是否對子孫全部檢索,默認為True soup.find_all('p', recursive = False) #string:<>...</>字符串區域的檢索字符串 soup.find_all(string = "Basic Python") import re soup.find_all(string = re.compile('Python')) #簡寫形式:soup(..) = soup.find_all(..)
拓展方法:參數同.find_all()
4.信息提取實例
中國大學排名定向爬蟲
功能描述:
? 輸入:大學排名URL鏈接
? 輸出:大學排名信息的屏幕輸出(排名,大學名稱,總分)
? 技術路線:requests-bs4
? 定向爬蟲:僅對輸入URL進行爬取,不拓展爬取
程序的結構設計:
? 步驟1:從網絡上獲取大學排名網頁內容
? getHTMLText()
? 步驟2:提取網頁內容中信息到合適的數據結構
? fillUnivList()
? 步驟3:利用數據結構展示并輸出結果
? printUnivList()
初步代碼編寫
import requests from bs4 import BeautifulSoup import bs4 ''' 這是小編準備的python爬蟲學習資料,加群:821460695 即可免費獲取! ''' def getHTMLText(url): try: r = requests.get(url, timeout= 30) r.raise_for_status() r.encoding = r.Apparent_encoding return r.text except: return "" def fillUnivList(ulist, html): soup = BeautifulSoup(html, "html.parser") for tr in soup.find('tbody').children: if isinstance(tr, bs4.element.Tag): tds = tr('td') ulist.append([tds[0].string, tds[1].string, tds[3].string]) def printUnivList(ulist, num): print("{:^10}t{:^6}t{:^10}".format("排名", "學校名稱", "分數")) for i in range(num): u = ulist[i] print("{:^10}t{:^6}t{:^10}".format(u[0], u[1], u[2])) def main(): uinfo = [] url = 'http://www.zuihaodaxue.cn/zuihaodaxuepaiming2016.html' html = getHTMLText(url) fillUnivList(uinfo,html) printUnivList(uinfo,20) #20 univs main()
中文輸出對齊問題
當輸出中文的寬度不夠時,系統會采用西文字符填充,導致對齊出現問題。
可以使用中文空格chr(12288)填充解決。
<填充> :用于填充的單個字符
<對齊> :<左對齊 >右對齊 ^居中對齊
<寬度> :槽的設定輸出寬度
, :數字的千位分隔符適用于整數和浮點數
<精度> :浮點數小數部分的精度或字符串的最大輸出長度
<類型> :整數類型b,c,d,o,x,X浮點數類型e,E,f,%
代碼優化
import requests from bs4 import BeautifulSoup import bs4 ''' 這是小編準備的python爬蟲學習資料,加群:821460695 即可免費獲取! ''' def getHTMLText(url): try: r = requests.get(url, timeout= 30) r.raise_for_status() r.encoding = r.apparent_encoding return r.text except: return "" def fillUnivList(ulist, html): soup = BeautifulSoup(html, "html.parser") for tr in soup.find('tbody').children: if isinstance(tr, bs4.element.Tag): tds = tr('td') ulist.append([tds[0].string, tds[1].string, tds[3].string]) def printUnivList(ulist, num): tplt = "{0:^10}t{1:{3}^10}t{2:^10}" print(tplt.format("排名", "學校名稱", "分數",chr(12288))) for i in range(num): u = ulist[i] print(tplt.format(u[0], u[1], u[2],chr(12288))) def main(): uinfo = [] url = 'http://www.zuihaodaxue.cn/zuihaodaxuepaiming2016.html' html = getHTMLText(url) fillUnivList(uinfo,html) printUnivList(uinfo,20) #20 univs main()