本文轉載於:原文
beautifulsoup 4 基礎教程
BeautifulSoup是python解析html非常好用的第三方庫!
抓取網頁信息的***強大幫手***
一、安裝
pip install beautifulsoup4
二、導入
form bs4 import BeautifulSoup
三、解析庫
BeautifulSoup默認支持Python的標准HTML解析庫,但是它也支持一些第三方的解析庫:
序號 | 解析庫 | 使用方法 | 優勢 | 劣勢 |
---|---|---|---|---|
1 | Python標准庫 | BeautifulSoup(html,’html.parser’) | Python內置標准庫;執行速度快 | 容錯能力較差 |
2 | lxml HTML解析庫 | BeautifulSoup(html,’lxml’) | 速度快;容錯能力強 | 需要安裝,需要C語言庫 |
3 | lxml XML解析庫 | BeautifulSoup(html,[‘lxml’,’xml’]) | 速度快;容錯能力強;支持XML格式 | 需要C語言庫 |
4 | htm5lib解析庫 | BeautifulSoup(html,’htm5llib’) | 以瀏覽器方式解析,最好的容錯性 | 速度慢 |
四、使用技巧
例如有這樣一個網頁html:
<!DOCTYPE html>
<!--STATUS OK-->
<html>
<head>
<meta content="text/html;charset=utf-8" http-equiv="content-type"/>
<meta content="IE=Edge" http-equiv="X-UA-Compatible"/>
<meta content="always" name="referrer"/>
<link href="https://ss1.bdstatic.com/5eN1bjq8AAUYm2zgoY3K/r/www/cache/bdorz/baidu.min.css" rel="stylesheet" type="text/css"/>
<title>
百度一下,你就知道 </title>
</head>
<body link="#0000cc">
<div id="wrapper">
<div id="head">
<div class="head_wrapper">
<div id="u1">
<a class="mnav" href="http://news.baidu.com" name="tj_trnews">
新聞 </a>
<a class="mnav" href="https://www.hao123.com" name="tj_trhao123">
hao123 </a>
<a class="mnav" href="http://map.baidu.com" name="tj_trmap">
地圖 </a>
<a class="mnav" href="http://v.baidu.com" name="tj_trvideo">
視頻 </a>
<a class="mnav" href="http://tieba.baidu.com" name="tj_trtieba">
貼吧 </a>
<a class="bri" href="//www.baidu.com/more/" name="tj_briicon" style="display: block;">
更多產品 </a>
</div>
</div>
</div>
</div>
</body>
</html>
創建beautifulsoup4對象:
from bs4 import BeautifulSoup
bs = BeautifulSoup(html,"html.parser")
縮進格式
print(bs.prettify())
獲取title標簽的所有內容
print(bs.title)
獲取title標簽的名稱
print(bs.title.name)
獲取title標簽的文本內容
print(bs.title.string)
獲取head標簽的所有內容
print(bs.head)
獲取第一個div標簽中的所有內容
print(bs.div)
獲取第一個div標簽的id的值
print(bs.div["id"])
獲取第一個a標簽中的所有內容
print(bs.a)
獲取所有的a標簽中的所有內容
print(bs.find_all("a"))
獲取id="u1"
print(bs.find(id="u1"))
獲取所有的a標簽,並遍歷打印a標簽中的href的值
for item in bs.find_all("a"):
print(item.get("href"))
獲取所有的a標簽,並遍歷打印a標簽的文本值
for item in bs.find_all("a"):
print(item.get_text())
五、BeautifulSoup4四大對象種類
BeautifulSoup4將復雜HTML文檔轉換成一個復雜的樹形結構,每個節點都是Python對象,所有對象可以歸納為4種:
(1)Tag
(2)NavigableString
(3)BeautifulSoup
(4)Comment
(1)Tag : Tag通俗點講就是HTML中的一個個標簽,例如:
from bs4 import BeautifulSoup
bs = BeautifulSoup(html,"html.parser")
獲取title標簽的所有內容
print(bs.title)
獲取head標簽的所有內容
print(bs.head)
獲取第一個a標簽的所有內容
print(bs.a)
類型
print(type(bs.a))
我們可以利用 soup 加標簽名輕松地獲取這些標簽的內容,這些對象的類型是 bs4.element.Tag。
但是注意,它查找的是在所有內容中的第一個符合要求的標簽。
對於 Tag,它有兩個重要的屬性,是 name 和 attrs:
# [document]
#bs 對象本身比較特殊,它的 name 即為 [document]
print(bs.name)
head
對於其他內部標簽,輸出的值便為標簽本身的名稱
print(bs.head.name)
在這里,我們把 a 標簽的所有屬性打印輸出了出來,得到的類型是一個字典。
print(bs.a.attrs)
還可以利用get方法,傳入屬性的名稱,二者是等價的
print(bs.a['class']) # bs.a.get('class')
可以對這些屬性和內容等等進行修改
bs.a['class'] = "newClass"
print(bs.a)
還可以對這個屬性進行刪除
del bs.a['class']
print(bs.a)
(2)NavigableString:獲取標簽內部的文字用 .string 即可,例如:
print(bs.title.string)
print(type(bs.title.string))
(3)BeautifulSoup:表示的是一個文檔的內容。
大部分時候,可以把它當作 Tag 對象,是一個特殊的 Tag,我們可以分別獲取它的類型,名稱,以及屬性,例如:
print(type(bs.name))
print(bs.name)
print(bs.attrs)
(4)Comment:是一個特殊類型的 NavigableString 對象,其輸出的內容不包括注釋符號。
print(bs.a) # 此時不能出現空格和換行符,a標簽如下:
# <a class="mnav" href="http://news.baidu.com" name="tj_trnews"><!--新聞--></a>
print(bs.a.string) # 新聞
print(type(bs.a.string)) # <class 'bs4.element.Comment'>
六、遍歷文檔樹
(1).contents:獲取Tag的所有子節點,返回一個list
# tag的.content 屬性可以將tag的子節點以列表的方式輸出
print(bs.head.contents)
用列表索引來獲取它的某一個元素
print(bs.head.contents[1])
(2).children:獲取Tag的所有子節點,返回一個生成器
for child in bs.body.children:
print(child)
七、搜索文檔樹
1. find_all(name, attrs, recursive, text, **kwargs)
(1)name參數:
字符串過濾:會查找與字符串完全匹配的內容
a_list = bs.find_all("a")
print(a_list)
正則表達式過濾:如果傳入的是正則表達式,那么BeautifulSoup4會通過search()來匹配內容
t_list = bs.find_all(re.compile("a"))
for item in t_list:
print(item)
列表: 如果傳入一個列表,BeautifulSoup4將會與列表中的任一元素匹配到的節點返回
t_list = bs.find_all(["meta","link"])
for item in t_list:
print(item)
方法: 傳入一個方法,根據方法來匹配
def name_is_exists(tag):
return tag.has_attr("name")
t_list = bs.find_all(name_is_exists)
for item in t_list:
print(item)
(2)kwargs參數:
# 查詢id=head的Tag
t_list = bs.find_all(id="head")
print(t_list)
查詢href屬性包含ss1.bdstatic.com的Tag
t_list = bs.find_all(href=re.compile("http://news.baidu.com"))
print(t_list)
查詢所有包含class的Tag(注意:class在Python中屬於關鍵字,所以加_以示區別)
t_list = bs.find_all(class_=True)
for item in t_list:
print(item)
(3)attrs參數:
並不是所有的屬性都可以使用上面這種方式進行搜索,比如HTML的data-*屬性,我們可以使用attrs參數,定義一個字典來搜索包含特殊屬性的tag:
t_list = bs.find_all(attrs={"data-foo":"value"})
for item in t_list:
print(item)
(4)text參數:
通過text參數可以搜索文檔中的字符串內容,與name參數的可選值一樣。
text參數接受 字符串,正則表達式,列表
t_list = bs.find_all(attrs={"data-foo": "value"})
for item in t_list:
print(item)
t_list = bs.find_all(text="hao123")
for item in t_list:
print(item)
t_list = bs.find_all(text=["hao123", "地圖", "貼吧"])
for item in t_list:
print(item)
t_list = bs.find_all(text=re.compile("\d"))
for item in t_list:
print(item)
(5)limit參數:
傳入一個limit參數來限制返回的數量
例如下列放回數量為2
t_list = bs.find_all("a",limit=2)
for item in t_list:
print(item)
2.find()
返回符合條件的第一個Tag
即當我們要取一個值的時候就可以用這個方法
t = bs.div.div
等價於
t = bs.find("div").find("div")
八、CSS選擇器
(1)通過標簽名查找
print(bs.select('title'))
print(bs.select('a'))
(2)通過類名查找
print(bs.select('.mnav'))
(3)通過id查找
print(bs.select('#u1'))
(4)組合查找
print(bs.select('div .bri'))
(5)屬性查找
print(bs.select('a[class="bri"]'))
print(bs.select('a[href="http://tieba.baidu.com"]'))
(6)獲取內容
t_list = bs.select("title")
print(bs.select('title')[0].get_text())