from bs4 import BeautifulSoup
import requests
r = requests.get("http://python123.io/ws/demo.html")
print r.text
print BeautifulSoup(r.text,'html.parser').prettify()
BeautifulSoup的基本元素
BS4庫是解析,遍歷,維護“標簽樹”的功能庫
BeautifulSoup庫 指代一個標簽樹
BeautifulSoup庫對應於一個HTML或XML文檔的全部內容
BS庫的解析器
解析器 | 使用方法 | 條件 |
bs4的HTML解析器 | BeautifulSoup(mk,'html.parser') | 安裝bs4庫 |
lxml的HTML解析器 | BeautifulSoup(mk,'lxml') | pip install lxml |
lxml的XML解析器 | BeautifulSoup(mk,'xml') | pip install lxml |
html5lib的解析器 | BeautifulSoup(mk,'html5lib') | pip install html5lib |
基本元素 | 說明 |
Tag | 標簽,最基本的信息組織單元,分別用<>和</>標明開頭和結尾 |
Name | 標簽的名字,<p>...</p>的名字的'p',格式:<tag>.name |
Attributes | 標簽的屬性,字典形式組織,格式<tag>.attrs |
NavigableString | 標簽內非屬性字符串,<>...</>中的字符串,格式:<tag>.string |
Comment | 標簽內字符串的注釋部分,一種特殊的Comment類型<!--comment--> |
soup.<tag>

BS庫的HTML文檔的遍歷
標簽樹的下行遍歷
屬性 | 說明 |
.contents | 子節點的列表,將<tag>所有兒子節點存入列表 |
.children | 子節點的迭代類型,與.contents類似,用於循環遍歷兒子的節點 |
.descendants | 子孫節點的迭代類型,包含所有子孫節點,用於循環遍歷 |
from bs4 import BeautifulSoup
import requests
r = requests.get("http://python123.io/ws/demo.html")
demo = r.text
s = BeautifulSoup(demo,'html.parser')
print s.prettify()
print s.body.contents
for child in s.body.children:
print(child)
for child in s.body.descendants:
print(child)
標簽樹的上午遍歷
屬性 | 說明 |
.parent | 節點的父親標簽 |
.parents | 節點先輩標簽的迭代類型,用於循環遍歷先輩節點 |
from bs4 import BeautifulSoup
import requests
r = requests.get("http://python123.io/ws/demo.html")
demo = r.text
s = BeautifulSoup(demo,'html.parser')
print s.prettify()
for parent in s.a.parents:
if parent is None:
print parent
else:
print parent.name
平行遍歷
屬性 | 說明 |
.next_sibiling | 返回按照HTML文本順序的下一個平行節點的標簽 |
.previous_sililing | 返回按照HTML文本順序的止一個平行節點的標簽 |
.next_sibilings | 迭代類型,返回按照HTML文本順序的后續所有平行節點的標簽 |
.previous_sibilings | 迭代類型,返回按照HTML文本順序的前續所有平行節點的標簽 |


信息標記的三種形式
HTML語言可以將超文件內容(即聲音,圖片,視頻等內容)嵌入到文本當中
XML擴展標記語言

實例

JSON JavaScript Object Notation
key:value鍵值對

實例

YMAL
采用無類型的鍵值對來表示信息

實例

標記語言 | 特點 | 應用場景 |
XML | 最早的通用信息標記語言,可擴展性好,但繁瑣 | Internet上的信息交互與傳遞 |
JSON | 信息有類型,適合程序處理(js),較XML簡潔 | 移動應用雲端和節點的信息通信,無注釋 |
YAML | 信息無類型,文本信息比例較高,可讀性較好 | 種類系統的配置文件,有注釋易讀 |
XML JSON YAML 搜索
需要標記解析器及文本查找函數
實例:解析一個文檔中的所有鏈接信息
from bs4 import BeautifulSoup
import requests
r = requests.get("http://python123.io/ws/demo.html")
demo = r.text
s = BeautifulSoup(demo,'html.parser')
for link in s.find_all('a'):
print link.get('href')
<>.find_all(name,attrs,recursive,string,**kwargs)
name: 需要檢索的標簽的名字,可以是列表,是True的話將返回所有的標簽
attrs: 要檢索的標簽的屬性值 ,e.g. soup.find_all('p','course') soup.find_all(id='link1')
soup.find_all(id = re.compile(u'link'))
recursive: 是否遞歸的檢索子孫后代節點,默認是True
string: <>...</>中的字符串區域的檢索字符串 soup.find_all(string = re.compile(u'python'))
<tag>(...)來代替<tag>.find_all(...)
soup.(...)來代替soup
.find_all(...)

實例1:中國大學排名的定向爬蟲
版本1
#CrawUnivRankingA.py
import requests
from bs4 import BeautifulSoup
import bs4
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()
輸出

版本2
#CrawUnivRankingB.py
import requests
from bs4 import BeautifulSoup
import bs4
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()
輸出
