一、bs4的使用
安裝:pip3 install Beautifulsoup4
1.bs4遍歷文檔樹
bs4:解析xml格式的模塊,從xml中找想要的數(shù)據(jù)。
html是xml的一種,解析html,使用requests返回的數(shù)據(jù),可能是json、html、文件,再使用bs4解析html格式。
用法:
from bs4 import BeautifulSoup
html_doc = """
<html><head><title>The Dormouse's story</title></head>
<body>
<p class="title" id='id_p' xx='xx'>我是帥哥<b>The Dormouse's story <span>xxx</span></b></p>
<p class="story">Once upon a time there were three little sisters; and their names were
<a class="sister" id="link1">Elsie</a>
<a class="sister" id="link2">Lacie</a> and
<a class="sister" id="link3">Tillie</a>;
and they lived at the bottom of a well.</p>
<p class="story">...</p>
"""
# soup = BeautifulSoup(html_doc, 'html.parser')
# 速度比上面快,但是需要安裝lxml模塊 pip3 install lxml
soup = BeautifulSoup(html_doc, 'lxml')
res = soup.prettify() # 美化
print(res)
# ----------遍歷文檔樹----------
# 1、用法 通過 .
body = soup.body # 直接通過soup對象.標(biāo)簽名,找到標(biāo)簽對象
print(type(body))
print(body.p)
# bs4.element.Tag 標(biāo)簽對象可以繼續(xù)往下 .
# 2、獲取標(biāo)簽的名稱
p = soup.p
print(p.name)
# 3、獲取標(biāo)簽的屬性
p=soup.p
print(p.attrs) # 把p標(biāo)簽所有屬性變成字典
print(p.attrs['class']) # class 是列表形式---->因為class有多個
print(p['id']) # 獲取屬性第二種方式
# 獲取第一個a標(biāo)簽的href屬性
a=soup.html.body.a['href']
print(a)
# 4、獲取標(biāo)簽的內(nèi)容
# text string strings
# 獲取第一個p標(biāo)簽的文本內(nèi)容
p = soup.p
print(p.text) # 獲取p子子孫孫所有的文本內(nèi)容,拼到一起
print(p.string) # p標(biāo)簽有且只有文本才能取出,如果有子標(biāo)簽,取出空
print(list(p.strings)) # 把子子孫孫的文本內(nèi)容放到迭代器中
# 5、嵌套選擇
p = soup.html.body.p
print(p)
# ----------只做了解----------
# 6、子節(jié)點、子孫節(jié)點
print(soup.p.contents) # p下所有子節(jié)點(不包含孫),是列表形式
print(list(soup.p.children)) #得到一個迭代器,包含p下所有子節(jié)點
print(list(soup.p.descendants)) # 子子孫
# 7、父節(jié)點、祖先節(jié)點
print(soup.a.parent) #獲取a標(biāo)簽的父節(jié)點
print(list(soup.a.parents)) #找到a標(biāo)簽所有的祖先節(jié)點,父親的父親,父親的父親的父親...
# 8、兄弟節(jié)點
print(soup.a.next_sibling) #下一個兄弟,緊鄰的,不一定是標(biāo)簽
print(soup.a.previous_sibling) #上一個兄弟
print(list(soup.a.next_siblings)) #下面的兄弟們=>生成器對象
print(list(soup.a.previous_siblings)) #上面的兄弟們=>生成器對象
注:lxml比html.parser速度塊,但是需要安裝lxml模塊(pip3 install lxml
)
2.bs4搜索文檔樹
搜索文檔樹速度是比遍歷慢一些的。
五種過濾器:
字符串、正則表達式、列表、True、方法
兩種方法:
find:找到的第一個 find_all:找到的所有
用法:
from bs4 import BeautifulSoup
html_doc = """
<html><head><title>The Dormouse's story</title></head>
<body>
<p class="title" id='id_p' xx='xx'>我是帥哥<b>The Dormouse's story <span>xxx</span></b></p>
<p class="story">Once upon a time there were three little sisters; and their names were
<a class="sister" id="link1">Elsie</a>
<a class="sister" id="link2">Lacie</a> and
<a class="sister" id="link3">Tillie</a>;
and they lived at the bottom of a well.</p>
<p class="story">...</p>
"""
soup = BeautifulSoup(html_doc, 'lxml')
# 字符串:指的的 屬性='字符串形式'
res=soup.find_all(name='body')
res=soup.find(name='body')
res=soup.find(class_='story') # class 是關(guān)鍵字,需要寫成class_
res=soup.find(id='link2')
res=soup.find(href='http://example.com/lacie')
# 如果傳多個參數(shù),表示并列 and條件‘
res=soup.find(attrs={'class':'story'})
print(res)
# 正則表達式
import re
print(soup.find_all(name=re.compile('^b'))) #找出b開頭的標(biāo)簽,結(jié)果有body和b標(biāo)簽
# 找到所有所有連接的標(biāo)簽
res=soup.find_all(href=re.compile('^http://'))
res=soup.find_all(href=re.compile('.*?lie$'))
res=soup.find_all(id=re.compile('^id'))
print(res)
# 列表
res=soup.find_all(name=['p','a'])
res=soup.find_all(class_=['title','story'])
print(len(res))
# 布爾
res=soup.find_all(name=True)
res=soup.find_all(href=True)
res=soup.find_all(src=True) # 把當(dāng)前頁面的圖片拿出來
print(res)
# 方法(了解)
def has_class_but_no_id(tag):
return tag.has_attr('class') and not tag.has_attr('id')
print(soup.find_all(has_class_but_no_id))
案例:
import requests
res=requests.get('https://www.pearvideo.com/category_loading.jsp?reqType=5&categoryId=9&start=12&mrd=0.013926765110156447')
soup=BeautifulSoup(res.text,'lxml')
li_list=soup.find_all(name='li',class_='categoryem')
for li in li_list:
res=li.div.a['href']
print(res)
li_list=soup.find_all(href=True,name='a',class_='vervideo-lilink')
print(li_list)
3.bs4其他用法
遍歷和搜索,可以混合用
recursive :是否遞歸查找
limit:查找多少條
用法:
from bs4 import BeautifulSoup
html_doc = """
<html><head><title>The Dormouse's story</title></head>
<body>
<p class="title" id='id_p' xx='xx'>我是帥哥<b>The Dormouse's story <span>xxx</span></b></p>
<p class="story">Once upon a time there were three little sisters; and their names were
<a class="sister" id="link1">Elsie</a>
<a class="sister" id="link2">Lacie</a> and
<a class="sister" id="link3">Tillie</a>;
and they lived at the bottom of a well.</p>
<p class="story">...</p>
"""
soup = BeautifulSoup(html_doc, 'lxml')
# 遍歷和搜索,可以混合用
res=soup.html.body.find('p')
res = soup.find('p')
print(res)
# recursive :是否遞歸查找
res=soup.html.body.find_all(name='p',recursive=False)
print(res)
# limit 查找多少條
res=soup.find_all('p',limit=2)
print(len(res))
補充:
1 鏈?zhǔn)秸{(diào)用(跟語言沒關(guān)系)
class Person:
def change_name(self, name):
self.name = name
return self
def change_age(self, age):
self.age = age
return self
def __str__(self):
try:
return '我的名字是:%s,我的年齡是:%s' % (self.name, self.age)
except:
return super().__str__()
p = Person()
p.change_name('egon').change_age(14)
print(p)
2 bs4支持修改文檔樹,對爬蟲沒用,對實際寫后臺代碼有用
3 主流軟件的配置文件方式
xxx.conf(redis,nginx)
xxx.ini(mysql)
xxx.xml(uwsgi,java的配置文件居多)
xxx.yaml
4 css選擇器
所有解析庫,通常會有自己的查找方式(bs4就是find和find_all),還會支持css和想xpath選擇。
記住一些css選擇器用法:
id#
類名.
標(biāo)簽名p
標(biāo)簽名>標(biāo)簽名 緊鄰的子
標(biāo)簽名 標(biāo)簽名 子子孫孫
res=soup.select('#id_p')
res=soup.select('p>a')
print(res)
5 xpath:在xml中查找文檔的語言文章來源:http://www.zghlxwxcb.cn/news/detail-520082.html
6 css、xpath都不會寫怎么辦
終極大招:瀏覽器F12選中頁面元素,鼠標(biāo)右擊選擇xpath或css復(fù)制即可~~
示例:文章來源地址http://www.zghlxwxcb.cn/news/detail-520082.html
# css
# maincontent > div:nth-child(3) > table > tbody > tr:nth-child(44) > td:nth-child(3)
# xpath
# //*[@id="maincontent"]/div[2]/table/tbody/tr[44]/td[3]
到了這里,關(guān)于解析庫bs4的使用的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!