一嗓奢、正則匹配
- 匹配單個字符與數(shù)字
----------匹配單個字符與數(shù)字---------
. 匹配除換行符以外的任意字符
[0123456789] []是字符集合,表示匹配方括號中所包含的任意一個字符
[good] 匹配good中任意一個字符
[a-z] 匹配任意小寫字母
[A-Z] 匹配任意大寫字母
[0-9] 匹配任意數(shù)字浑厚,類似[0123456789]
[0-9a-zA-Z] 匹配任意的數(shù)字和字母
[0-9a-zA-Z_] 匹配任意的數(shù)字股耽、字母和下劃線
[^good] 匹配除了good這幾個字母以外的所有字符,中括號里的^稱為脫字符钳幅,表示不匹配集合中的字符
[^0-9] 匹配所有的非數(shù)字字符
\d 匹配數(shù)字物蝙,效果同[0-9]
\D 匹配非數(shù)字字符,效果同[^0-9]
\w 匹配數(shù)字敢艰,字母和下劃線,效果同[0-9a-zA-Z_]
\W 匹配非數(shù)字茬末,字母和下劃線,效果同[^0-9a-zA-Z_]
\s 匹配任意的空白符(空格盖矫,回車丽惭,換行,制表辈双,換頁)责掏,效果同[ \r\n\t\f]
\S 匹配任意的非空白符,效果同[^ \f\n\r\t]
- 匹配邊界字符
--------------錨字符(邊界字符)-------------
^ 行首匹配湃望,和在[]里的^不是一個意思 startswith
$ 行尾匹配 endswith
\A 匹配字符串開始换衬,它和^的區(qū)別是,\A只匹配整個字符串的開頭,即使在re.M模式下也不會匹配它行的行首
\Z 匹配字符串結(jié)束证芭,它和$的區(qū)別是,\Z只匹配整個字符串的結(jié)束瞳浦,即使在re.M模式下也不會匹配它行的行尾
\b 匹配一個單詞的邊界,也就是值單詞和空格間的位置 bounds
\B 匹配非單詞邊界
- 匹配分組
#匹配分組
#| :或
#() :整體
#search:會在字符串中從左向左進(jìn)行查找废士,如果找到第一個符合條件的叫潦,則停止查找
#正則1|正則2:只要正則1或者正則2中的一個滿足,則直接按照這個條件查找
- 模式修正
re.I:忽略大小寫模式【ignorecase】
re.M:視為多行模式【more】
re.S:視為單行模式【single】
二官硝、Xpath解析
在 XPath 中矗蕊,有七種類型的節(jié)點(diǎn):元素短蜕、屬性、文本傻咖、命名空間朋魔、處理指令、注釋以及文檔(根)節(jié)點(diǎn)卿操。XML 文檔是被作為節(jié)點(diǎn)樹來對待的警检。樹的根被稱為文檔節(jié)點(diǎn)或者根節(jié)點(diǎn)。
- test.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>測試頁面</title>
</head>
<body>
<ol>
<li class="haha pp">醉臥沙場君莫笑害淤,古來征戰(zhàn)幾人回</li>
<li class="heihei">兩岸猿聲啼不住解滓,輕舟已過萬重山</li>
<li id="hehe" class="nene">一騎紅塵妃子笑,無人知是荔枝來</li>
<li class="xixi">停車坐愛楓林晚筝家,霜葉紅于二月花</li>
<li class="lala">商女不知亡國恨,隔江猶唱后庭花</li>
</ol>
<div id="pp">
<div>
<a >李白</a>
</div>
<ol>
<li class="huanghe">君不見黃河之水天上來邻辉,奔流到海不復(fù)回</li>
<li id="tata" class="hehe">李白乘舟將欲行溪王,忽聞岸上踏歌聲</li>
<li class="tanshui">桃花潭水深千尺,不及汪倫送我情</li>
</ol>
<div class="hh">
<a >雷軍</a>
</div>
<ol>
<li class="dudu">are you ok</li>
<li class="meme">會飛的豬</li>
</ol>
</div>
</body>
</html>
- 運(yùn)用
from lxml import etree
#用etree把整個html字符串加載出來值骇,生成一顆節(jié)點(diǎn)樹
html = etree.HTML(r.text) # r.text是文本類型
# 1莹菱、根據(jù)樹形結(jié)構(gòu)獲取目標(biāo)節(jié)點(diǎn)
res = html_tree.xpath('/html/body/ol/li[3]')
res = html_tree.xpath('/html/body/div/div[2]/a')
# 2、查找節(jié)點(diǎn)中的內(nèi)容和屬性
res = html_tree.xpath('/html/body/div/ol[1]/li[1]/text()') # ['君不見黃河之水天上來吱瘩,奔流到海不復(fù)回']
# xpath 語法中節(jié)點(diǎn)的屬性需要用@符號修飾
res = html_tree.xpath('/html/body/div/div[2]/a/@href') #['http://mi.com']
# 3道伟、定位
#(1)層級定位 '/' 代表節(jié)點(diǎn)前面有一層 '//' 代表有若干層
res = html_tree.xpath('//li/text()')
*** text()只獲得當(dāng)前節(jié)點(diǎn)的文本內(nèi)容***
****string() 會獲得當(dāng)前節(jié)點(diǎn)下的子孫節(jié)點(diǎn)所有文本***
# (2)屬性定位
# 獲取頁面中有class屬性的li的元素
res = html_tree.xpath('//li[@id]')
# 獲取所有的class值為hehe的li
res = html_tree.xpath('//li[@class="hehe"]')
# 如果一個節(jié)點(diǎn)的某個屬性有多個值一定要把這些值寫全
res = html_tree.xpath('//li[@class="haha pp"]')
# 4、模糊匹配
# 查找所有class值以h開頭的li
res = html_tree.xpath('//li[starts-with(@class,"h")]')
# 查找所有class值中含有a的li
res = html_tree.xpath('//li[contains(@class,"h")]')
# 5使碾、邏輯運(yùn)算
# 查找所有class值為hehe并且id值為tata的li元素
res = html_tree.xpath('//li[@class="hehe" and @id="tata"]')
# 查找所有class值為hehe或者含有a的元素
res = html_tree.xpath('//li[@class="hehe" or contains(@class,"a")]')
obj = html_tree.xpath("http://div[@id='pp']")[0]
#以obj為根節(jié)點(diǎn)蜜徽,繼續(xù)向內(nèi)部查找
res = obj.xpath('//li/text()') # 無論以誰為根,以'//'開頭都是以html為根節(jié)點(diǎn)
res = obj.xpath('.//li/text()') # 以'.//'開頭是以當(dāng)前節(jié)點(diǎn)(obj)開始匹配
三票摇、BS4解析
- 樣本html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>soup測試</title>
</head>
<body>
<div class="tang">
<ul>
<li><a title="出塞"><!--秦時明月漢時關(guān)拘鞋,萬里長征人未還,但使龍城飛將在矢门,-->不教胡馬度陰山</a></li>
<li><a class="taohua">人面不知何處去盆色,桃花依舊笑春風(fēng)</a></li>
<li><a id="hong">去年今日此門中,人面桃花相映紅</a></li>
<li><a name="he">故人西辭黃鶴樓祟剔,煙花三月下?lián)P州</a></li>
</ul>
</div>
<div id="meng">
<p class="jiang">
<span>三國猛將</span>
<ol>
<li>關(guān)羽</li>
<li>張飛</li>
<li>趙云</li>
<li>馬超</li>
<li>黃忠</li>
</ol>
<div class="cao">
<ul>
<li>典韋</li>
<li>許褚</li>
<li>張遼</li>
<li>張郃</li>
<li>于禁</li>
<li>夏侯惇</li>
</ul>
</div>
</p>
</div>
</body>
</html>
- 解析
from bs4 import BeautifulSoup
# 1)隔躲、把html字符串初始化成一個BeautifulSoup對象
soup = BeautifulSoup(open("./soup_test.html",encoding='utf-8'),'lxml')
# 參數(shù)1,一個htnml字符串 參數(shù)2,是一個解析器(bs4沒有自己的解析器物延,如果加入其它的解析器宣旱,可以提高其解析效率 )
# 1、根據(jù)標(biāo)簽名來查找對象叛薯,這類方法返回的是這類標(biāo)簽的第一個
# print(soup.title) #<title>soup測試</title>
# print(soup.li)
#2响鹃、獲取標(biāo)簽的內(nèi)容
obj = soup.a
# print(obj.string) # 獲取頁面中字符串(包括被注釋的內(nèi)容)驾霜,string屬性如果有多個子節(jié)點(diǎn),無法獲取
# print(obj.get_text()) # 獲取當(dāng)前標(biāo)簽中的字符串(包括所有后代標(biāo)簽中的字符串)买置,無法獲取注釋內(nèi)容
# 3粪糙、獲取屬性
# print(obj.get('title')) # 用get方法獲取屬性內(nèi)容
# print(obj['href']) # 用字典鍵值獲取
# print(obj.attrs) # 獲取標(biāo)簽的所有屬性(得到一個字典)
# print(obj.name) # 獲取標(biāo)簽的名
# 4、獲取子節(jié)點(diǎn)
# print(soup.body.children) #<list_iterator object at 0x000002098C3E5EF0>
#獲取直接子節(jié)點(diǎn)
# for child in soup.body.children:
# print('------------------')
# print(child)
print(soup.body.descendants)
# 獲取當(dāng)前節(jié)點(diǎn)的所有后代節(jié)點(diǎn)
# for i in soup.body.descendants:
# print('------------------')
# print(i)
# 5忿项、根據(jù)相關(guān)函數(shù)查找節(jié)點(diǎn)
# 1) find函數(shù)蓉冈,返回一個對象
# print(soup.find('a')) #尋找第一個a標(biāo)簽
# print(soup.find('',id='hong'))
# 2)find_all函數(shù),返回的是一個列表
# print(soup.find_all('a'))
# print(soup.find_all(['a','span','li']))
# print(soup.find_all(['a','span','li'],limit = 3))
# print(soup.find_all(['a','span','li'],class='taohua'))
# 3)select函數(shù)轩触,根據(jù)css選擇器來查找
# print(soup.select('.taohua'))
# print(soup.select('.tang ul li')) #派生
# print(soup.select('li#hong')) # 組合(先查找li標(biāo)簽然后找含有id是hong的li)
# print(soup.select('[name="he"]')) # 屬性選擇器
四寞酿、jsonpath解析
- 樣本json
{ "store": {
"book": [
{ "category": "reference",
"author": "李白",
"title": "Sayings of the Century",
"price": 8.95
},
{ "category": "fiction",
"author": "杜甫",
"title": "Sword of Honour",
"price": 12.99
},
{ "category": "fiction",
"author": "白居易",
"title": "Moby Dick",
"isbn": "0-553-21311-3",
"price": 8.99
},
{ "category": "fiction",
"author": "蘇軾",
"title": "The Lord of the Rings",
"isbn": "0-395-19395-8",
"price": 22.99
}
],
"bicycle": {
"color": "red",
"price": 19.95
}
}
}
- 解析
import json
import jsonpath
books = json.load(open('./book.json','r',encoding='utf-8'))
# print(books['store'])
# print(books['store']['book'])
# print(books['store']['book'][1]['price'])
# 查找所有的book的價(jià)格
b = books['store']['book']
# for i in b:
# print(i['price'])
# 用jsonpath查找
# /html/body/div
# 在jsonpath中$代表根節(jié)點(diǎn)、 "." 代表當(dāng)前節(jié)點(diǎn)的子節(jié)點(diǎn)脱柱, ".." 代表當(dāng)前節(jié)點(diǎn)的后代節(jié)點(diǎn)
res = jsonpath.jsonpath(books,"$.store.book[*]")
res = jsonpath.jsonpath(books,"$..author")
res = jsonpath.jsonpath(books,"$..book[:3]")
print(res)