本文主要圍繞以xpath和lxml庫進行展開:
為永城等地區(qū)用戶提供了全套網(wǎng)頁設計制作服務,及永城網(wǎng)站建設行業(yè)解決方案。主營業(yè)務為網(wǎng)站制作、成都網(wǎng)站建設、永城網(wǎng)站設計,以傳統(tǒng)方式定制建設網(wǎng)站,并提供域名空間備案等一條龍服務,秉承以專業(yè)、用心的態(tài)度為用戶提供真誠的服務。我們深信只要達到每一位用戶的要求,就會得到認可,從而選擇與我們長期合作。這樣,我們也可以走得更遠!
一、xpath 概念、xpath節(jié)點、xpath語法、xpath軸、xpath運算符
二、lxml的安裝、lxml的使用、lxml案例
一、xpath
1.xpath概念
XPath 是一門在 XML 文檔中查找信息的語言。XPath 使用路徑表達式在 XML 文檔中進行導航 。XPath 包含一個標準函數(shù)庫 。XPath 是 XSLT 中的主要元素 。XPath 是一個 W3C 標準 。
2.xpath節(jié)點
xpath有七種類型的節(jié)點:元素、屬性、文本、命名空間、處理指令、注釋以及文檔(根)節(jié)點。
節(jié)點關(guān)系:父、子、兄弟、先輩、后輩。
3.xpath語法
xpath語法在W3c網(wǎng)站上有詳細的介紹,這里截取部分知識,供大家學習。
XPath 使用路徑表達式在 XML 文檔中選取節(jié)點。節(jié)點是通過沿著路徑或者 step 來選取的。下面列出了最有用的路徑表達式:
在下面的表格中,我們已列出了一些路徑表達式以及表達式的結(jié)果:
謂語用來查找某個特定的節(jié)點或者包含某個指定的值的節(jié)點。
謂語被嵌在方括號中。
在下面的表格中,我們列出了帶有謂語的一些路徑表達式,以及表達式的結(jié)果:
XPath 通配符可用來選取未知的 XML 元素。
在下面的表格中,我們列出了一些路徑表達式,以及這些表達式的結(jié)果:
通過在路徑表達式中使用"|"運算符,您可以選取若干個路徑。
在下面的表格中,我們列出了一些路徑表達式,以及這些表達式的結(jié)果:
4.xpath 軸
軸可定義相對于當前節(jié)點的節(jié)點集。
5.xpath運算符
下面列出了可用在 XPath 表達式中的運算符:
好了,xpath的內(nèi)容就這么多了。接下來我們要介紹一個神器lxml,他的速度很快,曾經(jīng)一直是我使用beautifulsoup時最鐘愛的解析器,沒有之一,因為他的速度的確比其他的html.parser 和html5lib快了許多。
二、lxml
1.lxml安裝
lxml 是一個xpath格式解析模塊,安裝很方便,直接pip install lxml 或者easy_install lxml即可。
2.lxml 使用
lxml提供了兩種解析網(wǎng)頁的方式,一種是你解析自己寫的離線網(wǎng)頁時,另一種 則是解析線上網(wǎng)頁。
導入包:
1.解析離線網(wǎng)頁:
2.解析在線網(wǎng)頁:
那么我們怎么獲取這些標簽和標簽對應的屬性值了,很簡單,首先獲取標簽只需你這樣做:
然后我們可以,比方說,你要獲取a標簽內(nèi)的文本和它的屬性href所對應的值,有兩種方法,
1.表達式內(nèi)獲取
2.表達式外獲取
這樣就完成了獲取,怎么樣,是不是很簡單了,哈哈哈。
下面再來lxml的解析規(guī)則:
3.lxml案例
為了偷懶,我決定還是采用urllib那篇文章的代碼,哈哈哈,機智如我。
lambda是個匿名函數(shù)而已, 這里就是產(chǎn)生了字典{True:f1, False f2},字典的兩個值就是2個函數(shù),f1 就是shutil.copy(...),f2就是copytree了,你可以理解成兩個函數(shù)指針。
bresult是個true或者false的值,后面[bresult]():就表示,根據(jù)bresult的結(jié)果調(diào)用前面字典里面對應的兩個函數(shù)。bresult在這里是字典的key。函數(shù)在這里是字典的value.
剛學用Python的時候,特別是看一些庫的源碼時,經(jīng)常會看到func(*args, **kwargs)這樣的函數(shù)定義,這個*和**讓人有點費解。其實只要把函數(shù)參數(shù)定義搞清楚了,就不難理解了。
先說說函數(shù)定義,我們都知道,下面的代碼定義了一個函數(shù)funcA
def funcA():
pass
顯然,函數(shù)funcA沒有參數(shù)(同時啥也不干:D)。
下面這個函數(shù)funcB就有兩個參數(shù)了,
def funcB(a, b):
print a
print b
調(diào)用的時候,我們需要使用函數(shù)名,加上圓括號擴起來的參數(shù)列表,比如 funcB(100, 99),執(zhí)行結(jié)果是:
100
99
很明顯,參數(shù)的順序和個數(shù)要和函數(shù)定義中一致,如果執(zhí)行funcB(100),Python會報錯的:
TypeError: funcB() takes exactly 2 arguments (1 given)
我們可以在函數(shù)定義中使用參數(shù)默認值,比如
def funcC(a, b=0):
print a
print b
在函數(shù)funcC的定義中,參數(shù)b有默認值,是一個可選參數(shù),如果我們調(diào)用funcC(100),b會自動賦值為0。
OK,目前為止,我們要定義一個函數(shù)的時候,必須要預先定義這個函數(shù)需要多少個參數(shù)(或者說可以接受多少個參數(shù))。一般情況下這是沒問題的,但是也有在定義函數(shù)的時候,不能知道參數(shù)個數(shù)的情況(想一想C語言里的printf函數(shù)),在Python里,帶*的參數(shù)就是用來接受可變數(shù)量參數(shù)的。看一個例子
def funcD(a, b, *c):
print a
print b
print "length of c is: %d " % len(c)
print c
調(diào)用funcD(1, 2, 3, 4, 5, 6)結(jié)果是
1
2
length of c is: 4
(3, 4, 5, 6)
我們看到,前面兩個參數(shù)被a、b接受了,剩下的4個參數(shù),全部被c接受了,c在這里是一個tuple。我們在調(diào)用funcD的時候,至少要傳遞2個參數(shù),2個以上的參數(shù),都放到c里了,如果只有兩個參數(shù),那么c就是一個empty tuple。
好了,一顆星我們弄清楚了,下面輪到兩顆星。
上面的例子里,調(diào)用函數(shù)的時候,傳遞的參數(shù)都是根據(jù)位置來跟函數(shù)定義里的參數(shù)表匹配的,比如funcB(100, 99)和funcB(99, 100)的執(zhí)行結(jié)果是不一樣的。在Python里,還支持一種用關(guān)鍵字參數(shù)(keyword argument)調(diào)用函數(shù)的辦法,也就是在調(diào)用函數(shù)的時候,明確指定參數(shù)值付給那個形參。比如還是上面的funcB(a, b),我們通過這兩種方式調(diào)用
funcB(a=100, b=99)
和
funcB(b=99, a=100)
結(jié)果跟funcB(100, 99)都是一樣的,因為我們在使用關(guān)鍵字參數(shù)調(diào)用的時候,指定了把100賦值給a,99賦值給b。也就是說,關(guān)鍵字參數(shù)可以讓我們在調(diào)用函數(shù)的時候打亂參數(shù)傳遞的順序!
另外,在函數(shù)調(diào)用中,可以混合使用基于位置匹配的參數(shù)和關(guān)鍵字參數(shù),前題是先給出固定位置的參數(shù),比如
def funcE(a, b, c):
print a
print b
print c
調(diào)用funcE(100, 99, 98)和調(diào)用funcE(100, c=98, b=99)的結(jié)果是一樣的。
好了,經(jīng)過以上鋪墊,兩顆星總算可以出場了:
如果一個函數(shù)定義中的最后一個形參有 ** (雙星號)前綴,所有正常形參之外的其他的關(guān)鍵字參數(shù)都將被放置在一個字典中傳遞給函數(shù),比如:
def funcF(a, **b):
print a
for x in b:
print x + ": " + str(b[x])
調(diào)用funcF(100, c='你好', b=200),執(zhí)行結(jié)果
100
c: 你好
b: 200
大家可以看到,b是一個dict對象實例,它接受了關(guān)鍵字參數(shù)b和c。
1.1 例如:print(hex(2))案例
1.2 輸出函數(shù):print(hex(2))
1.3 輸出結(jié)果:0x2
1.4 解析說明:返回16進制的數(shù)。
2.1 例如:print(chr(10))案例
2.2 輸出函數(shù):print(chr(10))
2.3 輸出結(jié)果:0o12
2.4 解析說明:返回當前整數(shù)對應的ASCll碼
3.1 例如:print(ord("b"))案例
3.2 輸出函數(shù):print(ord("b"))
3.3 輸出結(jié)果:98
3.4 解析說明:返回當前ASCll碼的10進制數(shù)
4.1 例如:print(chr(97))
4.2 輸出函數(shù):print(chr(97))
4.3 輸出結(jié)果:b
4.4 解析說明:返回當前ASCll碼的10進制數(shù)。
案例一:給你一個字符串,s = 'hello kitty'
1.1 輸出函數(shù):print(s.capitalize())
1.2 輸出結(jié)果:0x2
1.3 解析說明:返回16進制的數(shù)。
2.1輸出函數(shù):print(s.replace('kitty','kuang'))
2.2 輸出結(jié)果:hello kuang
2.3 解析說明:替換功能,將kitty換成kuang。
2.4 輸出函數(shù):print(s.replace('4','KK'))
2.5 輸出結(jié)果:12KK12KK
2.6 解析說明:所有的4都替換成KK
2.7 輸出函數(shù):print(s.replace('4','KK'))
2.8 輸出結(jié)果:12KK12KK124
2.9 解析說明:將前兩個的4替換成go
案例一:給你一個字符串,ip = '192.168.1.1'
3.1 輸出函數(shù):print(ip.split(','))
3.2 輸出結(jié)果:['192.168.1.1']
3.3 解析說明:將字符串分割成列表
案例一:給你一個字符串,ip = '192.168.1.1'
3.3 輸出函數(shù):print(ip.split(',',2))
3.4 輸出結(jié)果:['192.168.1.1']
3.5 解析說明:從第二個開始分割成列表
以python 3.8.5150.0版本為例,python中eval函數(shù)作用如下:
1、計算字符串中有效的表達式,并返回結(jié)果。
2、將字符串轉(zhuǎn)成相應的對象(如list、tuple、dict和string之間的轉(zhuǎn)換)。
3、將利用反引號轉(zhuǎn)換的字符串再反轉(zhuǎn)回對象。
參數(shù)解析:
expression:這個參數(shù)是一個字符串,python會使用globals字典和locals字典作為全局和局部的命名空間,將expression當作一個python表達式進行解析和計算。
globals:這個參數(shù)控制的是一個全局的命名空間,也就是我們在計算表達式的時候可以使用全局的命名空間中的函數(shù),如果這個參數(shù)被提供了。
并且沒有提供自定義的builtins(python的內(nèi)建模塊),那么會將當前環(huán)境中的builtins拷貝到提供的globals里,然后進行計算。如果globals沒有被提供,則使用python的全局命名空間。
locals:這個參數(shù)控制的是一個局部的命名空間,和globals類似,不過當它和globals中有重復的部分時,locals里的定義會覆蓋掉globals中的,也就是說當globals和locals中有沖突的部分時,locals說了算,它有決定權(quán),以它的為準。如果locals沒有被提供的話,則默認為globals。
python中的函數(shù),大多需要配置參數(shù),以下是幾種函數(shù)的參數(shù)類型:
1.必備參數(shù):以正確的順序、個數(shù)傳入函數(shù)。調(diào)用時的參數(shù)情況要和聲明時一樣。最常用的情況。
def tplink(a,b):
c=a+b+b
return c?
tplink(4,2)
2.關(guān)鍵字參數(shù):使用關(guān)鍵字參數(shù)允許函數(shù)調(diào)用時參數(shù)的順序和聲明時不一致,因為python解析器會在調(diào)用函數(shù)時,用參數(shù)名匹配參數(shù)值。
def tplink(age1,age2):
ageall=age1+age2+age2
return ageall
tplink(age2=4,age1=2)
3.默認參數(shù):默認某個參數(shù)的取值
def tplink(age1,age2=5):
ageall=age1+age2+age2
return ageall
tplink(age1=4)
4.不定長參數(shù):在聲明時并不確定 調(diào)用時的參數(shù)數(shù)量。這種情況,可以用不定長參數(shù)進行解決,具體操作是在參數(shù)名前用*。
但不能和 關(guān)鍵字參數(shù)并用。一般在正常參數(shù)arg之后。
*args、**kwargs的定義:
這兩個都是python中的不定長參數(shù),又稱為可變參數(shù)。
*args 表示任何多個無名參數(shù),它是一個 tuple ;
**kwargs 表示關(guān)鍵字參數(shù),它是一個dict。
同時使用 * args和 ** kwargs 時,必須 * args參數(shù)列要在 ** kwargs前。且都在arg之后。
函數(shù)在調(diào)用時,會根據(jù)順序,看是否放進 *args 或者 **kwargs中。
具體可根據(jù)實際情況使用,可以 更方便靈活的接收信息。