《Python網(wǎng)絡(luò)爬蟲基礎(chǔ)教程》 課件-第4章 解析網(wǎng)頁數(shù)據(jù)_第1頁
《Python網(wǎng)絡(luò)爬蟲基礎(chǔ)教程》 課件-第4章 解析網(wǎng)頁數(shù)據(jù)_第2頁
《Python網(wǎng)絡(luò)爬蟲基礎(chǔ)教程》 課件-第4章 解析網(wǎng)頁數(shù)據(jù)_第3頁
《Python網(wǎng)絡(luò)爬蟲基礎(chǔ)教程》 課件-第4章 解析網(wǎng)頁數(shù)據(jù)_第4頁
《Python網(wǎng)絡(luò)爬蟲基礎(chǔ)教程》 課件-第4章 解析網(wǎng)頁數(shù)據(jù)_第5頁
已閱讀5頁,還剩124頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

第4章解析網(wǎng)頁數(shù)據(jù)《Python網(wǎng)絡(luò)爬蟲基礎(chǔ)教程》學(xué)習(xí)目標(biāo)/Target了解解析網(wǎng)頁的技術(shù),能夠說出正則表達(dá)式、Xpath、BeautifulSoup與JSONPath的特點(diǎn)熟悉正則表達(dá)式的語法,能夠歸納元字符與預(yù)定義字符集的含義掌握re模塊的用法,能夠靈活應(yīng)用re模塊解析網(wǎng)頁數(shù)據(jù)了解XPath的概念,能夠說出XPath的路徑表達(dá)式的搜索方法學(xué)習(xí)目標(biāo)/Target掌握XPath的語法,能夠編寫XPath的路徑表達(dá)式掌握XPath的開發(fā)工具,能夠獨(dú)立安裝與使用XPathHelper工具掌握lxml庫(kù)的用法,能夠靈活應(yīng)用lxml庫(kù)解析網(wǎng)頁數(shù)據(jù)熟悉BeautifulSoup,能夠歸納BeautifulSoup包含的類的基本用法學(xué)習(xí)目標(biāo)/Target掌握BeautifulSoup類對(duì)象的創(chuàng)建方式,能夠使用BeautifulSoup類的構(gòu)造方法創(chuàng)建BeautifulSoup類的對(duì)象掌握BeautifulSoup中選取節(jié)點(diǎn)的方式,能夠使用查找方法和CSS選擇器選取節(jié)點(diǎn)熟悉JSONPath的語法,能夠熟練地編寫JSONPath的表達(dá)式掌握jsonpath模塊的用法,能夠靈活運(yùn)用jsonpath模塊解析JSON文檔章節(jié)概述/Summary通過對(duì)第3章的學(xué)習(xí),我們已經(jīng)將整個(gè)靜態(tài)網(wǎng)頁的源代碼全部抓取下來了,并且源代碼包含了最終要提取的數(shù)據(jù)。這些數(shù)據(jù)分為非結(jié)構(gòu)化數(shù)據(jù)和結(jié)構(gòu)化數(shù)據(jù)兩種。由于這兩種數(shù)據(jù)各有各的特點(diǎn),因此需要采用不同的技術(shù)進(jìn)行解析,提取與目標(biāo)有關(guān)的數(shù)據(jù)。本章將圍繞著解析網(wǎng)頁數(shù)據(jù)的相關(guān)知識(shí)進(jìn)行詳細(xì)講解。目錄/Contents4.14.24.3解析網(wǎng)頁數(shù)據(jù)的技術(shù)正則表達(dá)式與re模塊XPath與lxml庫(kù)目錄/Contents4.44.54.6BeautifulSoup庫(kù)JSONPath與jsonpath模塊實(shí)踐項(xiàng)目:采集黑馬程序員論壇的帖子解析網(wǎng)頁數(shù)據(jù)的技術(shù)4.1了解解析網(wǎng)頁的技術(shù),能夠說出正則表達(dá)式、Xpath、BeautifulSoup與JSONPath的作用學(xué)習(xí)目標(biāo)4.1解析網(wǎng)頁數(shù)據(jù)的技術(shù)Python中提供了多種解析網(wǎng)頁數(shù)據(jù)的技術(shù),包括正則表達(dá)式、XPath、BeautifulSoup、JSONPath。4.1解析網(wǎng)頁數(shù)據(jù)的技術(shù)正則表達(dá)式XPathBeautifulSoupJSONPath正則表達(dá)式是一種文本模式,這種模式描述了匹配字符串的規(guī)則,用于檢索字符串中是否有符合該模式的子串,或者對(duì)匹配到的子串進(jìn)行替換。正則表達(dá)式的優(yōu)點(diǎn)是功能強(qiáng)大,應(yīng)用廣泛,缺點(diǎn)是只適合匹配文本的字面意義,而不適合匹配文本意義。例如,正則表達(dá)式在匹配嵌套了HTML內(nèi)容的文本時(shí),會(huì)忽略HTML內(nèi)容本身存在的層次結(jié)構(gòu),而是將HTML內(nèi)容作為普通文本進(jìn)行搜索。Python中提供了多種解析網(wǎng)頁數(shù)據(jù)的技術(shù),包括正則表達(dá)式、XPath、BeautifulSoup、JSONPath。4.1解析網(wǎng)頁數(shù)據(jù)的技術(shù)正則表達(dá)式XPathBeautifulSoupJSONPathXPath是XML路徑語言,用于從HTML或XML格式的數(shù)據(jù)中提取所需的數(shù)據(jù)。XPath適合處理層次結(jié)構(gòu)比較明顯的數(shù)據(jù),它能夠基于HTML或XML的節(jié)點(diǎn)樹確定目標(biāo)節(jié)點(diǎn)所在的路徑,順著這個(gè)路徑便可以找到節(jié)點(diǎn)對(duì)應(yīng)的文本或?qū)傩灾怠ython中提供了多種解析網(wǎng)頁數(shù)據(jù)的技術(shù),包括正則表達(dá)式、XPath、BeautifulSoup、JSONPath。4.1解析網(wǎng)頁數(shù)據(jù)的技術(shù)正則表達(dá)式XPathBeautifulSoupJSONPathBeautifulSoup是一個(gè)可以從HTML或XML文件中提取數(shù)據(jù)的Python庫(kù),它同樣可以使用XPath語法提取數(shù)據(jù),并且也在此基礎(chǔ)上做了方便開發(fā)者的封裝,提供了更多選取節(jié)點(diǎn)的方式。Python中提供了多種解析網(wǎng)頁數(shù)據(jù)的技術(shù),包括正則表達(dá)式、XPath、BeautifulSoup、JSONPath。正則表達(dá)式XPathBeautifulSoupJSONPathJSONPath的作用類似XPath,它也是以表達(dá)式的方式解析數(shù)據(jù)的,但只能解析JSON格式的數(shù)據(jù)。4.1解析網(wǎng)頁數(shù)據(jù)的技術(shù)若要解析純文本,則可以選擇正則表達(dá)式;若要解析HTML或XML格式的數(shù)據(jù),則可以選擇正則表達(dá)式、XPath、BeautifulSoup;若要解析JSON格式的數(shù)據(jù),則可以選擇JSONPath。為便于開發(fā)者使用這些技術(shù),Python提供了一些庫(kù)或模塊進(jìn)行支持,包括re、lxml、bs4、jsonpath,其中re模塊支持正則表達(dá)式;lxml庫(kù)和bs4庫(kù)支持XPath;jsonpath模塊支持JSONPath。4.1解析網(wǎng)頁數(shù)據(jù)的技術(shù)正則表達(dá)式與re模塊4.2熟悉正則表達(dá)式的語法,能夠歸納元字符與預(yù)定義字符集的含義學(xué)習(xí)目標(biāo)4.2.1正則表達(dá)式的語法正則表達(dá)式是對(duì)字符串操作的一種邏輯公式,它會(huì)將事先定義好的一些特定字符,以及這些特定字符的組合,組成一個(gè)規(guī)則字符串,并且通過這個(gè)規(guī)則字符串表達(dá)對(duì)給定字符串的過濾邏輯。一條正則表達(dá)式也稱為一個(gè)模式,使用每個(gè)模式可以匹配指定文本中與表達(dá)式模式相同的字符串。正則表達(dá)式由普通字符、元字符或預(yù)定義字符集組成,其中普通字符包括大小寫字母和數(shù)字。4.2.1正則表達(dá)式的語法

元字符在正則表達(dá)式中,元字符是指具有特殊含義的專用字符,主要用于規(guī)定其前導(dǎo)字符在給定字符串中出現(xiàn)的模式。4.2.1正則表達(dá)式的語法元字符說明.匹配任何一個(gè)字符(除換行符外)^匹配字符串的開頭$匹配字符串的末尾|連接多個(gè)子表達(dá)式,匹配與任意子表達(dá)式模式相同的字符串[]字符組,匹配其中的出現(xiàn)的任意一個(gè)字符-連字符,匹配指定范圍內(nèi)的任意一個(gè)字符?匹配其前導(dǎo)字符0次或1次*匹配其前導(dǎo)字符0次或多次+匹配其前導(dǎo)字符1次或多次{n}匹配其前導(dǎo)字符n次{m,n}匹配其前導(dǎo)字符m~n次()分組,匹配子組

預(yù)定義字符集在正則表達(dá)式中,除了前面介紹的元字符之外,還預(yù)定義了一些字符集,這些字符集以更加簡(jiǎn)潔的方式描述了一些由普通字符和元字符組合的模式。4.2.1正則表達(dá)式的語法預(yù)定義字符集說明\w匹配下畫線“_”或任何字母(a~z,A~Z)與數(shù)字(0~9)\s匹配任意的空白字符,等價(jià)于[<空格>\t\r\n\f\v]\d匹配任意數(shù)字,等價(jià)于[0-9]

\b匹配單詞的邊界\W與\w相反,匹配非字母或數(shù)字或下畫線的字符\S與\s相反,匹配任意非空白字符的字符,等價(jià)于[^\s]\D與\d相反,匹配任意非數(shù)字的字符,等價(jià)于[^\d]\B與\b相反,匹配不出現(xiàn)在單詞邊界的元素\A僅匹配字符串開頭,等價(jià)于^\Z僅匹配字符串結(jié)尾,等價(jià)于$掌握re模塊的用法,能夠靈活應(yīng)用re模塊解析網(wǎng)頁數(shù)據(jù)學(xué)習(xí)目標(biāo)4.2.2re模塊的使用4.2.2re模塊的使用Python中提供了re模塊操作正則表達(dá)式,該模塊中提供了豐富的函數(shù)或方法來實(shí)現(xiàn)文本匹配查找、文本替換、文本分割等功能。re模塊的使用一般可以分為兩步,分別是創(chuàng)建Pattern對(duì)象和全文匹配。4.2.2re模塊的使用為了節(jié)省每次編譯正則表達(dá)式的開銷,保證正則表達(dá)式可以重復(fù)使用,我們可以使用compile()函數(shù)對(duì)正則表達(dá)式進(jìn)行預(yù)編譯,從而生成一個(gè)代表正則表達(dá)式的Pattern對(duì)象。

創(chuàng)建Pattern對(duì)象4.2.2re模塊的使用compile(pattern,flags=0)以上函數(shù)中,參數(shù)pattern表示一個(gè)正則表達(dá)式;參數(shù)flags用于指定正則表達(dá)式匹配的模式,該參數(shù)的常用取值及其含義如下。re.I:忽略大小寫。re.L:做本地化識(shí)別(locale-aware)匹配,使預(yù)定義字符集\w、\W、\b、\B、\s、\S取決于當(dāng)前區(qū)域設(shè)定。re.M:多行匹配,影響“^”和“$”。re.S:使字符“.”匹配所有字符,包括換行符。re.U:根據(jù)Unicode字符集匹配字符。re.A:根據(jù)ASCII字符集匹配字符。re.X:允許使用更靈活的格式(多行、忽略空白字符、加入注釋)書寫正則表達(dá)式。

創(chuàng)建Pattern對(duì)象4.2.2re模塊的使用如果希望從全部文本中匹配所有符合正則表達(dá)式的字符串,則可以使用Pattern對(duì)象的findall()與finditer()函數(shù),其中findall()函數(shù)用于獲取目標(biāo)文本中所有與正則表達(dá)式匹配的內(nèi)容,并將所有匹配的內(nèi)容以列表的形式返回;finditer()函數(shù)同樣可以獲取目標(biāo)文本中所有與正則表達(dá)式匹配的內(nèi)容,但該方法會(huì)將匹配到的子串以迭代器的形式返回。

全文匹配findall(pattern,string,flags=0)findall()函數(shù)的聲明如下:4.2.2re模塊的使用

全文匹配pattern:表示一個(gè)正則表達(dá)式。string:表示待匹配的文本。flags:用于指定正則表達(dá)式匹配的模式,該參數(shù)支持的取值與compile()函數(shù)中參數(shù)flags的取值相同。4.2.2re模塊的使用importrestring="狗的英文:dog,貓的英文:cat。"reg_zhn=pile(r"[\u4e00-\u9fa5]+")print(re.findall(reg_zhn,string))以字符串“狗的英文:dog,貓的英文:cat。”為例,使用findall()函數(shù)匹配該字符串中所有的中文,示例代碼如下所示:運(yùn)行代碼,結(jié)果如下所示:['狗的英文','貓的英文']

全文匹配XPath與lxml庫(kù)4.3正則表達(dá)式雖然可以處理包含了諸如HTML或XML內(nèi)容的字符串,但是它只能根據(jù)文本的特征匹配字符串,而忽略了字符串中包含內(nèi)容的真實(shí)格式。為了解決這個(gè)問題,Python中引入了XPath以及支持XPath的第三方庫(kù)lxml,專門對(duì)XML或HTML格式的數(shù)據(jù)進(jìn)行解析。4.3XPath與lxml庫(kù)了解XPath的概念,能夠說出XPath的路徑表達(dá)式的作用學(xué)習(xí)目標(biāo)4.3.1XPath簡(jiǎn)介XPath即XML路徑語言(全稱XmlPathLanguage),是一種用于確定XML文檔中部分節(jié)點(diǎn)位置的語言,它起初只支持搜索XML文檔,更新后也支持搜索HTML文檔。4.3.1XPath簡(jiǎn)介4.3.1XPath簡(jiǎn)介XPath是如何搜索XML或HTML文檔?4.3.1XPath簡(jiǎn)介其實(shí)XPath基于XML或HTML的節(jié)點(diǎn)樹,沿著節(jié)點(diǎn)樹的節(jié)點(diǎn)關(guān)系定位到目標(biāo)節(jié)點(diǎn)所在的位置,并選取節(jié)點(diǎn)或節(jié)點(diǎn)集。為了形象地描述出搜索節(jié)點(diǎn)的路徑,XPath提供了簡(jiǎn)潔明了的路徑表達(dá)式,通過路徑表達(dá)式可以快速地定位與選取XML或HTML文檔中的一個(gè)節(jié)點(diǎn)或者一組節(jié)點(diǎn)集。與正則表達(dá)式相比路徑表達(dá)式有什么區(qū)別?正則表達(dá)式路徑表達(dá)式與正則表達(dá)式相比,路徑表達(dá)式的搜索方式大不相同,這里我們借用一個(gè)形象的例子進(jìn)行比較。假如我們把選取目標(biāo)節(jié)點(diǎn)比作找金燕龍辦公樓,如果我們通過正則表達(dá)式查找,則正則表達(dá)式會(huì)告訴你辦公樓有哪些特征,辦公樓的左邊有哪些建筑,右邊有哪些建筑,這樣的描述限定的查找范圍比較寬泛,查找起來比較繁瑣;如果采用路徑表達(dá)式查找,則路徑表達(dá)式會(huì)直接告訴你辦公樓的具體位置,即中國(guó)北京市昌平區(qū)建材城西路金燕龍辦公樓一層,這樣的描述更加精準(zhǔn),更易查找。4.3.1XPath簡(jiǎn)介正則表達(dá)式路徑表達(dá)式路徑表達(dá)式描述了從一個(gè)節(jié)點(diǎn)到另一個(gè)節(jié)點(diǎn)或一組節(jié)點(diǎn)的順序,它與在常規(guī)的計(jì)算機(jī)文件系統(tǒng)中見到的路徑非常相似。例如,“/學(xué)生名單/班級(jí)/學(xué)生/籍貫”就是一個(gè)路徑表達(dá)式,該路徑表達(dá)式也是用“/”字符進(jìn)行分隔的,只不過它分隔的是節(jié)點(diǎn),而不是目錄。4.3.1XPath簡(jiǎn)介與正則表達(dá)式相比路徑表達(dá)式有什么區(qū)別?通過一張示意圖來描述XML文檔、XML節(jié)點(diǎn)樹與路徑表達(dá)式的關(guān)系。正則表達(dá)式路徑表達(dá)式4.3.1XPath簡(jiǎn)介從左到右依次為XML文檔、XML節(jié)點(diǎn)樹和路徑表達(dá)式,其中路徑表達(dá)式為“/bookstore/book/price”,它對(duì)應(yīng)的路徑為圖中加粗的線條,用于選取節(jié)點(diǎn)<price>對(duì)應(yīng)的文本39.95。掌握XPath的語法,能夠編寫XPath的路徑表達(dá)式學(xué)習(xí)目標(biāo)4.3.2XPath語法4.3.2XPath語法如果要編寫一個(gè)路徑表達(dá)式,則要先了解XPath的語法,如此才能使用路徑表達(dá)式正確地選取節(jié)點(diǎn)。路徑表達(dá)式會(huì)從某個(gè)節(jié)點(diǎn)開始沿著節(jié)點(diǎn)樹查找節(jié)點(diǎn),直至找到目標(biāo)節(jié)點(diǎn)為止。由于節(jié)點(diǎn)的多樣性,為了幫助開發(fā)人員快速選取目標(biāo)節(jié)點(diǎn),XPath提供了一套語法規(guī)則。4.3.2XPath語法下面從選取節(jié)點(diǎn)、謂語、選取未知節(jié)點(diǎn)、選取若干路徑這4個(gè)方面介紹XPath的語法。選取節(jié)點(diǎn)謂語選取未知節(jié)點(diǎn)選取若干路徑選取節(jié)點(diǎn)是最基礎(chǔ)的操作,節(jié)點(diǎn)所在的路徑既可以是從根節(jié)點(diǎn)開始的,也可以從任意位置開始的。表達(dá)式說明節(jié)點(diǎn)名稱選取此節(jié)點(diǎn)的所有子節(jié)點(diǎn)/從根節(jié)點(diǎn)選取直接子節(jié)點(diǎn),相當(dāng)于絕對(duì)路徑//從當(dāng)前節(jié)點(diǎn)選取后代節(jié)點(diǎn),相當(dāng)于相對(duì)路徑.選取當(dāng)前節(jié)點(diǎn)..選取當(dāng)前節(jié)點(diǎn)的父節(jié)點(diǎn)@選取屬性節(jié)點(diǎn)下面以一個(gè)XML文檔bookstore.xml為例,演示通過XPath語法選取XML文檔中的節(jié)點(diǎn)。選取節(jié)點(diǎn)的示例4.3.2XPath語法<?xmlversion="1.0"encoding="ISO-8859-1"?><bookstore><book><titlelang="eng">HarryPotter</title><price>29.99</price></book><book><titlelang="eng">LearningXML</title><price>39.95</price></book></bookstore>bookstore#選取bookstore的所有子節(jié)點(diǎn)/bookstore#選取根節(jié)點(diǎn)bookstorebookstore/book#從根節(jié)點(diǎn)bookstore開始,向下選取名為book的所有子節(jié)點(diǎn)//book#從任意節(jié)點(diǎn)開始,選取名為book的所有子節(jié)點(diǎn)bookstore//book#從bookstore的后代節(jié)點(diǎn)中,選取名為book的所有子節(jié)點(diǎn)//@lang#選取所有名為lang的屬性節(jié)點(diǎn)4.3.2XPath語法選取節(jié)點(diǎn)謂語選取未知節(jié)點(diǎn)選取若干路徑謂語是為路徑表達(dá)式附加的條件,主要用于篩選當(dāng)前被處理的節(jié)點(diǎn)集,選取出滿足某個(gè)特定的節(jié)點(diǎn),或者包含了指定屬性或基本值的節(jié)點(diǎn)。謂語會(huì)嵌入到方括號(hào)中,位于要補(bǔ)充說明的節(jié)點(diǎn)后面。節(jié)點(diǎn)[謂語]方括號(hào)中的謂語可以是整數(shù)、屬性、函數(shù),也可以是整數(shù)、屬性、函數(shù)與運(yùn)算符組合的表達(dá)式。如果謂語是整數(shù)(從1開始),則這個(gè)數(shù)值將作為位置,用于從節(jié)點(diǎn)集中選取與該位置對(duì)應(yīng)的節(jié)點(diǎn);如果為屬性,則會(huì)從節(jié)點(diǎn)集中選取包含該屬性的節(jié)點(diǎn);如果為函數(shù),則會(huì)將該函數(shù)的返回值作為條件,從節(jié)點(diǎn)集中選取滿足條件的節(jié)點(diǎn)。4.3.2XPath語法常用的XPath函數(shù)如下表所示。函數(shù)說明position()返回當(dāng)前被處理的節(jié)點(diǎn)的位置last()返回當(dāng)前節(jié)點(diǎn)集中的最后一個(gè)節(jié)點(diǎn)count()返回節(jié)點(diǎn)的總數(shù)目max((arg,arg,...))返回大于其他參數(shù)的參數(shù)min((arg,arg,...))返回小于其他參數(shù)的參數(shù)name()返回當(dāng)前節(jié)點(diǎn)的名稱current-date()返回當(dāng)前的日期(帶有時(shí)區(qū))current-time()返回當(dāng)前的時(shí)間(帶有時(shí)區(qū))contains(string1,string2)若string1包含string2,則返回true,否則返回false選取節(jié)點(diǎn)謂語選取未知節(jié)點(diǎn)選取若干路徑以前面的bookstore.xml為例,演示帶謂語的路徑表達(dá)式的用法,具體代碼如下所示。4.3.2XPath語法/bookstore/book[1]#選取屬于bookstore子節(jié)點(diǎn)的第1個(gè)book節(jié)點(diǎn)/bookstore/book[last()]#選取屬于bookstore子節(jié)點(diǎn)的最后一個(gè)book節(jié)點(diǎn)/bookstore/book[last()-1]#選取屬于bookstore子節(jié)點(diǎn)的倒數(shù)第2個(gè)book節(jié)點(diǎn)/bookstore/book[position()<3]#選取屬于bookstore子節(jié)點(diǎn)的前兩個(gè)book節(jié)點(diǎn)//title[@lang]#選取所有的屬性名稱為lang的title節(jié)點(diǎn)//title[@lang='eng']#選取所有的屬性名稱為lang且屬性值為eng的title節(jié)點(diǎn)#選取子節(jié)點(diǎn)price的值大于35.00,且父節(jié)點(diǎn)為bookstore的所有book節(jié)點(diǎn)/bookstore/book[price>35.00]#選取屬于book的所有子節(jié)點(diǎn)title,且節(jié)點(diǎn)book的子節(jié)點(diǎn)price的值必須大于35.00/bookstore/book[price>35.00]/title4.3.2XPath語法選取節(jié)點(diǎn)謂語選取未知節(jié)點(diǎn)選取若干路徑XPath中提供了選取未知節(jié)點(diǎn)的通配符和函數(shù)。/bookstore/*#選取屬于bookstore的所有子節(jié)點(diǎn)//*#選取文檔中的所有節(jié)點(diǎn)//title[@*]#選取所有帶有屬性的節(jié)點(diǎn)title通配符/函數(shù)說明*匹配任何元素節(jié)點(diǎn)@*匹配任何屬性節(jié)點(diǎn)node()匹配任何類型的節(jié)點(diǎn)以bookstore.xml為例,演示通配符或函數(shù)的用法。4.3.2XPath語法選取節(jié)點(diǎn)謂語選取未知節(jié)點(diǎn)選取若干路徑在XPath中,我們可以使用“|”運(yùn)算符連接多個(gè)路徑表達(dá)式,以根據(jù)多個(gè)路徑選取對(duì)應(yīng)的節(jié)點(diǎn)。以bookstore.xml為例,演示“|”的用法。//book/title|//book/price#選取屬于book的子節(jié)點(diǎn)title和price//title|//price#選取所有的title和price節(jié)點(diǎn)#選取屬于/bookstore/book/的所有title節(jié)點(diǎn),以及文檔中所有的節(jié)點(diǎn)price/bookstore/book/title|//price掌握XPath的開發(fā)工具,能夠獨(dú)立安裝與使用XPathHelper工具學(xué)習(xí)目標(biāo)4.3.3XPath開發(fā)工具XPathHelper是一款運(yùn)行在Chrome瀏覽器的插件,它支持在網(wǎng)頁上單擊元素生成路徑表達(dá)式,也支持對(duì)照網(wǎng)頁源代碼手動(dòng)編寫路徑表達(dá)式。在使用XPathHelper測(cè)試之前,我們需要先在Chrome瀏覽器上添加XPathHelper插件。4.3.3XPath開發(fā)工具4.3.3XPath開發(fā)工具步驟1步驟2步驟3安裝XPathHelper插件在Chrome瀏覽器的右上角單擊按鈕打開自定義及控制GoogleChrome菜單,在該菜單中單擊“更多工具”→“擴(kuò)展程序”進(jìn)入擴(kuò)展程序頁面。4.3.3XPath開發(fā)工具步驟2步驟1步驟3安裝XPathHelper插件將XPathHelper.crx文件拖入到擴(kuò)展程序頁面中,可以看到該頁面中增加了擴(kuò)展程序XPathHelper,打開該擴(kuò)展程序?qū)?yīng)的開啟按鈕,此時(shí)擴(kuò)展程序頁面的右上角位置顯示了XPathHelper的圖標(biāo)

。4.3.3XPath開發(fā)工具步驟3步驟1步驟2安裝XPathHelper插件單擊圖標(biāo)可以看到瀏覽器頂部彈出一個(gè)XPathHelper界面。界面左側(cè)的編輯區(qū)域用于輸入路徑表達(dá)式,右側(cè)區(qū)域用于展示通過該路徑表達(dá)式選取的結(jié)果,并且會(huì)將結(jié)果總數(shù)目(默認(rèn)顯示的值為0)顯示到RESULTS后面的括號(hào)里面。4.3.3XPath開發(fā)工具步驟1步驟2步驟3使用XPathHelper插件在瀏覽器中打開豆瓣電影首頁,在該頁面中單擊“排行榜”→“喜劇”進(jìn)入喜劇電影排行榜首頁。喜劇電影排行榜首頁中默認(rèn)展示20部電影,當(dāng)滾動(dòng)條滑至頁面底部時(shí),會(huì)有新的電影加載到頁面中。在該頁面頂部第一部電影名稱“美麗人生”的上方單擊鼠標(biāo)右鍵,打開快捷菜單,在該菜單中選擇“檢查”。頁面底部彈出了帶Elements的界面,并定位到了電影名稱“美麗人生”對(duì)應(yīng)元素源代碼的位置。4.3.3XPath開發(fā)工具步驟2步驟1步驟3安裝XPathHelper插件分析上頁圖中元素的層次結(jié)構(gòu)后,推斷出最終的路徑表達(dá)式可以為://div[@class='movie-info']/div/span/a/text()需要說明的是,路徑表達(dá)式并不是唯一的,既可以是從根節(jié)點(diǎn)開始的絕對(duì)路徑,也可以是從任意節(jié)點(diǎn)開始的相對(duì)路徑。4.3.3XPath開發(fā)工具步驟3步驟1步驟2安裝XPathHelper插件打開XPathHelper工具,在左側(cè)的編輯區(qū)域中輸入上述路徑表達(dá)式,此時(shí)右側(cè)區(qū)域中展示了選取的結(jié)果及數(shù)目。掌握lxml庫(kù)的用法,能夠靈活應(yīng)用lxml庫(kù)解析網(wǎng)頁數(shù)據(jù)學(xué)習(xí)目標(biāo)4.3.4lxml庫(kù)簡(jiǎn)介4.3.4lxml庫(kù)簡(jiǎn)介在lxml庫(kù)中,大多數(shù)有關(guān)解析的功能都封裝到

etree模塊中,etree模塊中包含了兩個(gè)比較重要的類,分別是ElementTree類和Element類。ElementTree類的對(duì)象可以理解為一個(gè)HTML或XML文檔的節(jié)點(diǎn)樹。為方便開發(fā)者將HTML或XML文檔轉(zhuǎn)換為ElementTree類的對(duì)象,etree模塊中提供了一個(gè)parse()函數(shù)。parse(source,parser=None,base_url=None)

ElementTree類4.3.4lxml庫(kù)簡(jiǎn)介source:必選參數(shù),表示待解析的內(nèi)容,該參數(shù)共支持4種類型的取值,分別是打開的文件對(duì)象(確保以二進(jìn)制模式打開)、類似文件的對(duì)象、字符串形式的文件名稱、字符串形式的URL。parser:可選參數(shù),表示解析器。若未指定解析器,則會(huì)使用默認(rèn)的解析器;若希望指定其他的解析器,則可以通過help(etree.XMLParser)查看lxml支持的解析器。base_url:可選參數(shù),表示基礎(chǔ)URL。以bookstore.xml為例,演示如何根據(jù)該文檔使用parse()函數(shù)創(chuàng)建ElementTree類的對(duì)象。fromlxmlimportetree#從bookstore.xml文件中解析,返回ElementTree類的對(duì)象ele_tree=etree.parse(r'bookstore.xml')print(type(ele_tree))

ElementTree類4.3.4lxml庫(kù)簡(jiǎn)介運(yùn)行代碼,結(jié)果如下所示。<class'lxml.etree._ElementTree'>

ElementTree類4.3.4lxml庫(kù)簡(jiǎn)介etree模塊中還提供了3個(gè)函數(shù):fromstring()、XML()和HTML(),這3個(gè)函數(shù)也可以解析HTML或XML文檔或片段,只不過在解析成功后返回根節(jié)點(diǎn)或者解析器目標(biāo)返回的結(jié)果。其中,fromstring()函數(shù)和XML()函數(shù)的功能相同,都可以從字符串常量中解析XML文檔或片段;HTML()函數(shù)用于從字符串常量中解析HTML文檔或片段,并能夠自動(dòng)補(bǔ)全文檔或片段中缺少的<html>和<body>元素。Element類的對(duì)象可以理解為XML或HTML文檔的節(jié)點(diǎn),它與Python中的列表非常相似,可以使用諸如len()、append()、remove()等方法修改節(jié)點(diǎn),也可以使用索引、切片獲取節(jié)點(diǎn)集中的子節(jié)點(diǎn)。print(root_node[:])

#獲取所有的子節(jié)點(diǎn)print(root_node[0])

#獲取第1個(gè)子節(jié)點(diǎn)print(root_node[1])

#獲取第2個(gè)子節(jié)點(diǎn)

Element類4.3.4lxml庫(kù)簡(jiǎn)介使用索引或切片獲取root_node對(duì)象中的子節(jié)點(diǎn),具體代碼如下所示。運(yùn)行代碼,結(jié)果如下所示:[<Elementbookat0x34cae00>,<Elementbookat0x34cae80>]<Elementbookat0x34cae00><Elementbookat0x34cae00>Element類還提供了一些獲取節(jié)點(diǎn)的屬性,關(guān)于這些屬性及其說明如下表。

Element類4.3.4lxml庫(kù)簡(jiǎn)介屬性說明tag獲取節(jié)點(diǎn)的名稱text獲取第一個(gè)子元素之前的文本。若沒有文本,則獲得的結(jié)果可以是字符串或Nonetail獲取當(dāng)前元素的結(jié)束標(biāo)記之后,下一個(gè)同級(jí)元素的開始標(biāo)記之前的文本。若沒有文本,則獲得的結(jié)果可以是字符串或Noneattrib獲取屬性節(jié)點(diǎn)的字典ElementTree類或Element類中提供了3個(gè)常用的查找方法,分別是find()、findall()、xpath(),這3個(gè)方法都會(huì)從節(jié)點(diǎn)樹的根節(jié)點(diǎn)開始查找目標(biāo)節(jié)點(diǎn)。

ElementTree類或Element類的查找方法4.3.4lxml庫(kù)簡(jiǎn)介find()方法:從節(jié)點(diǎn)樹的某個(gè)節(jié)點(diǎn)開始查找,返回匹配到的第一個(gè)子節(jié)點(diǎn)。findall()方法:從節(jié)點(diǎn)樹的某個(gè)節(jié)點(diǎn)開始查找,以列表的形式返回匹配到的所有子節(jié)點(diǎn)。xpath()方法:從節(jié)點(diǎn)樹的根節(jié)點(diǎn)或某個(gè)節(jié)點(diǎn)開始查找,以列表的形式返回匹配到的所有子節(jié)點(diǎn)。以上3個(gè)方法都可以接收XPath的路徑表達(dá)式,并在調(diào)用成功后返回查找到的最終結(jié)果,不過find()和findall()方法只支持相對(duì)路徑,xpath()方法支持相對(duì)路徑和絕對(duì)路徑。需要注意的是,若find()方法未找到匹配項(xiàng),則會(huì)返回None;若findall()和xpath()方法未找到匹配項(xiàng),則會(huì)返回一個(gè)空列表。以root_node對(duì)象為例,分別使用以上3個(gè)方法的查找第一個(gè)price節(jié)點(diǎn)的文本,示例代碼如下所示。

ElementTree類或Element類的查找方法4.3.4lxml庫(kù)簡(jiǎn)介res1=root_node.find('.//price').textprint(res1)res2=root_node.findall('.//price')[0].textprint(res2)res3=root_node.xpath('.//price')[0].textprint(res3)BeautifulSoup4.44.4BeautifulSoup在使用lxml庫(kù)解析網(wǎng)頁數(shù)據(jù)時(shí),每次都需要編寫和測(cè)試XPath的路徑表達(dá)式,顯得非常煩瑣。為了解決這個(gè)問題,Python還提供了BeautifulSoup提取HTML或XML文檔的節(jié)點(diǎn),BeautifulSoup使用起來更加便捷,受到了開發(fā)人員的推崇。熟悉BeautifulSoup,能夠歸納BeautifulSoup常用類的使用學(xué)習(xí)目標(biāo)4.4.1BeautifulSoup簡(jiǎn)介BeautifulSoup是一個(gè)用于從HTML或XML文檔中提取目標(biāo)數(shù)據(jù)的Python庫(kù),它歷經(jīng)了眾多版本,其中BeautifulSoup3目前已經(jīng)停止開發(fā)與維護(hù),官方推薦使用BeautifulSoup4(簡(jiǎn)稱為bs4)進(jìn)行開發(fā)。4.4.1BeautifulSoup簡(jiǎn)介為了快速解析HTML或XML文檔的數(shù)據(jù),bs4不僅提供了多種解析器,還支持CSS選擇器。bs4可以將HTML或XML文檔、片段轉(zhuǎn)換成節(jié)點(diǎn)樹,并會(huì)將整個(gè)節(jié)點(diǎn)樹中的每個(gè)節(jié)點(diǎn)看作一個(gè)Python類的對(duì)象。bs4庫(kù)或bs4.element模塊中提供了4個(gè)比較重要的類,分別是Tag類、NavigableString類、BeautifulSoup類和Comment類。4.4.1BeautifulSoup簡(jiǎn)介bs4.element.Tag類:表示HTML中的標(biāo)簽,是最基本的信息組織單元。它有兩個(gè)非常重要的屬性:表示標(biāo)簽名字的name,表示標(biāo)簽屬性的attrs。bs4.element.NavigableString類:表示HTML中標(biāo)簽的文本(非屬性字符串)。bs4.BeautifulSoup類:表示HTML或XML節(jié)點(diǎn)樹中的全部?jī)?nèi)容,支持遍歷節(jié)點(diǎn)樹和索文檔樹的大部分方法。bs4.element.Comment類:表示元素內(nèi)字符串的注釋部分,是一種特殊的NavigableString類的對(duì)象。4.4.1BeautifulSoup簡(jiǎn)介創(chuàng)建Beautiful類的對(duì)象定位節(jié)點(diǎn)提取節(jié)點(diǎn)123根據(jù)HTML或XML文檔或片段創(chuàng)建一個(gè)BeautifulSoup類的對(duì)象。通過BeautifulSoup類的對(duì)象的查詢方法或CSS選擇器定位節(jié)點(diǎn)。通過訪問節(jié)點(diǎn)的屬性或節(jié)點(diǎn)的名稱提取文本。BeautifulSoup的用法非常簡(jiǎn)單,一般分為如下3個(gè)步驟。掌握BeautifulSoup類對(duì)象的創(chuàng)建方式,能夠使用BeautifulSoup類的構(gòu)造方法創(chuàng)建BeautifulSoup類對(duì)象

學(xué)習(xí)目標(biāo)4.4.2創(chuàng)建BeautifulSoup類的對(duì)象4.4.2創(chuàng)建BeautifulSoup類的對(duì)象要想使用BeautifulSoup解析網(wǎng)頁,需要先使用構(gòu)造方法創(chuàng)建一個(gè)BeautifulSoup類的對(duì)象。BeautifulSoup(markup="",features=None,builder=None,parse_only=None,from_encoding=None,exclude_encodings=None,element_classes=None,**kwargs)markup:必選參數(shù),表示待解析的內(nèi)容,可以取值為字符串或類似文件的對(duì)象。features:可選參數(shù),表示指定的解析器。該參數(shù)可以接收解析器名稱或標(biāo)記類型,其中解析器名稱包括lxml、lxml-xml、html.parser和html5lib,標(biāo)記類型包括"html"、"html5"和"xml"。parse_only:可選參數(shù),用于指定只解析部分文檔,該參數(shù)需要接收一個(gè)SoupStrainer類的對(duì)象。from_encoding:可選參數(shù),用于指定待解析文檔的編碼格式。4.4.2創(chuàng)建BeautifulSoup類的對(duì)象值得一提的是,如果我們只需要解析HTML文檔,那么在創(chuàng)建BeautifulSoup類的對(duì)象時(shí)可以不用指定解析器,此時(shí)BeautifulSoup會(huì)根據(jù)當(dāng)前系統(tǒng)已經(jīng)安裝的庫(kù)自動(dòng)選擇解析器,選擇順序?yàn)閘xml→html5lib→Python標(biāo)準(zhǔn)庫(kù)。4.4.2創(chuàng)建BeautifulSoup類的對(duì)象如果指定的解析器沒有安裝,那么BeautifulSoup會(huì)自動(dòng)選擇其它方案。不過,目前只有解析器lxml支持XML文檔的解析,在當(dāng)前系統(tǒng)中沒有安裝解析器lxml的情況下,即便創(chuàng)建beautifulsoup對(duì)象時(shí)明確指定了使用解析器lxml,也無法得到解析后的對(duì)象。解析器優(yōu)勢(shì)劣勢(shì)lxml(lxml的HTML解析器)(1)執(zhí)行速度快(2)文檔容錯(cuò)能力強(qiáng)需要安裝C語言庫(kù)lxml-xml(lxml的XML解析器)(1)執(zhí)行速度快(2)唯一適用于XML文檔的解析器需要安裝C語言庫(kù)html.parser(bs4的HTML解析器)(1)Python內(nèi)置的標(biāo)準(zhǔn)庫(kù)(2)執(zhí)行速度適中(3)文檔容錯(cuò)能力強(qiáng)Python2.7.3或3.2.2之前的版本中文檔容錯(cuò)能力差html5lib(1)擁有4中解析器中最好的容錯(cuò)能力(2)以瀏覽器的方式解析文檔(3)生成HTML5格式的文檔(1)執(zhí)行速度慢(2)不依賴外部擴(kuò)展1frombs4importBeautifulSoup2html_doc="""<html><head><title>TheDormouse'sstory</title></head>3<body>4<pclass="title"><b>TheDormouse'sstory</b></p>5<pclass="story">Onceuponatimetherewerethreelittlesisters;6andtheirnameswere7<ahref="/elsie"class="sister"id="link1">Elsie</a>,8<ahref="/lacie"class="sister"id="link2">Lacie</a>and9<ahref="/tillie"class="sister"id="link3">Tillie</a>;10andtheylivedatthebottomofawell.</p>11<pclass="story">...</p>12"""13#根據(jù)html_doc創(chuàng)建BeautifulSoup類的對(duì)象,并指定使用lxml解析器解析文檔14soup=BeautifulSoup(html_doc,features='lxml')15print(soup.prettify())通過一個(gè)示例來演示如何創(chuàng)建BeautifulSoup類的對(duì)象,具體代碼如下所示。4.4.2創(chuàng)建BeautifulSoup類的對(duì)象<html><head><title>TheDormouse'sstory</title></head><body><pclass="title"><b>TheDormouse'sstory</b></p>……</body></html>在上頁示例代碼中,第1行代碼導(dǎo)入了BeautifulSoup類,第2~12行定義了變量html_doc保存HTML代碼片段,第14行代碼根據(jù)html_doc創(chuàng)建了BeautifulSoup類的一個(gè)對(duì)象,并指定使用解析器lxml來解析HTML文檔,第15行代碼輸出了soup.prettify()執(zhí)行的結(jié)果,其中prettify()方法會(huì)對(duì)HTML代碼片段進(jìn)行格式化處理,友好地顯示HTML代碼。4.4.2創(chuàng)建BeautifulSoup類的對(duì)象掌握BeautifulSoup中選取節(jié)點(diǎn)的方式,能夠使用查找方法選取節(jié)點(diǎn)學(xué)習(xí)目標(biāo)4.4.3通過查找方法選取節(jié)點(diǎn)find_all(self,name=None,attrs={},recursive=True,text=None,limit=None,**kwargs)BeautifulSoup類中提供了一些基于HTML或XML節(jié)點(diǎn)樹選取節(jié)點(diǎn)的方法,比較主流的兩個(gè)方法分別是find()和find_all(),find()方法用于查找符合條件的第一個(gè)節(jié)點(diǎn);find_all()方法用于查找所有符合條件的節(jié)點(diǎn),并以列表的形式進(jìn)行返回。4.4.3通過查找方法選取節(jié)點(diǎn)以上方法中包含了多個(gè)參數(shù),每個(gè)參數(shù)接收的值類型不同,查找到的結(jié)果也會(huì)有所不同。若值為字符串,則會(huì)查找名稱與字符串完全相同的所有節(jié)點(diǎn)。例如,使用創(chuàng)建的soup對(duì)象調(diào)用find_all()方法查找名稱為title的節(jié)點(diǎn),代碼如下所示。

參數(shù)name查找結(jié)果如下所示:[<title>TheDormouse'sstory</title>]4.4.3通過查找方法選取節(jié)點(diǎn)soup.find_all('title')若值為正則表達(dá)式,則會(huì)查找名稱符合正則表達(dá)式模式的所有節(jié)點(diǎn)。例如,使用soup對(duì)象調(diào)用find_all()方法查找id屬性值中含有l(wèi)ink1關(guān)鍵字的所有節(jié)點(diǎn),代碼如下所示。

參數(shù)name查找結(jié)果如下所示:4.4.3通過查找方法選取節(jié)點(diǎn)soup.find_all(id=pile("link1"))[<aclass="sister"href="/elsie"id="link1">Elsie</a>]若值為列表,則會(huì)查找名稱與列表中任一元素相同的所有節(jié)點(diǎn)。例如,使用soup對(duì)象調(diào)用find_all()方法查找所有名稱為title或a的節(jié)點(diǎn),代碼如下。

參數(shù)name查找結(jié)果如下所示:4.4.3通過查找方法選取節(jié)點(diǎn)soup.find_all(["title","a"])[<title>TheDormouse'sstory</title>,<aclass="sister"href="/elsie"id="link1">Elsie</a>,<aclass="sister"href="/lacie"id="link2">Lacie</a>,<aclass="sister"href="/tillie"id="link3">Tillie</a>]參數(shù)attrs表示待查找的屬性節(jié)點(diǎn),它接收一個(gè)字典,字典中的鍵為屬性名稱,值為該屬性對(duì)應(yīng)的值。例如,使用soup對(duì)象調(diào)用find_all()方法查找屬性名稱為id、值為link1的節(jié)點(diǎn),代碼如下。

參數(shù)attrs查找結(jié)果如下所示:4.4.3通過查找方法選取節(jié)點(diǎn)soup.find_all(attrs={'id':'link1'})[<aclass="sister"href="/elsie"id="link1">Elsie</a>]參數(shù)recursive表示是否對(duì)當(dāng)前節(jié)點(diǎn)的所有子孫節(jié)點(diǎn)進(jìn)行查找,其默認(rèn)值為True。如果我們只需要對(duì)當(dāng)前節(jié)點(diǎn)的直接子節(jié)點(diǎn)進(jìn)行查找,則可以將參數(shù)recursive的值設(shè)為False。例如,使用soup對(duì)象調(diào)用find_all()方法查找直接子節(jié)點(diǎn)<head>,代碼如下所示。

參數(shù)recursive查找結(jié)果如下所示:4.4.3通過查找方法選取節(jié)點(diǎn)soup.html.find_all("head",recursive=False)[<head><title>TheDormouse'sstory</title></head>]參數(shù)text表示待查找的文本節(jié)點(diǎn),它也支持字符串、正則表達(dá)式、列表3種類型的取值,具有與name參數(shù)的用法相同。例如,使用soup對(duì)象調(diào)用find_all()方法查找所有文本為Elsie的節(jié)點(diǎn),代碼如下所示。

參數(shù)text查找結(jié)果如下所示:4.4.3通過查找方法選取節(jié)點(diǎn)soup.find_all(text="Elsie")['Elsie']參數(shù)limit表示待查找的節(jié)點(diǎn)數(shù)量。當(dāng)在節(jié)點(diǎn)樹中尋找節(jié)點(diǎn)時(shí),如果節(jié)點(diǎn)樹非常大,那么查找的速度會(huì)非常慢。此時(shí)若不需要選取所有符合要求的結(jié)果,可以給limit參數(shù)指定值以限制結(jié)果的數(shù)量,一旦數(shù)量超過了limit參數(shù)的值,就會(huì)停止查找。參數(shù)limit與SQL語句中l(wèi)imit語句達(dá)到的效果類似,都可以限制查找結(jié)果的最大數(shù)量。例如,使用soup對(duì)象調(diào)用find_all()方法查找至多1個(gè)節(jié)點(diǎn)<a>,代碼如下所示。

參數(shù)limit查找結(jié)果如下所示:4.4.3通過查找方法選取節(jié)點(diǎn)soup.find_all("a",limit=1)[<aclass="sister"href="/elsie"id="link1">Elsie</a>]參數(shù)**kwargs支持以關(guān)鍵字形式傳遞的任意個(gè)參數(shù)。在節(jié)點(diǎn)樹中尋找節(jié)點(diǎn)時(shí),會(huì)將關(guān)鍵字參數(shù)的名稱作為節(jié)點(diǎn)的屬性名稱,值作為屬性值。例如,使用soup對(duì)象調(diào)用find_all()方法查找屬性名稱為id、值為link3的節(jié)點(diǎn),代碼如下所示。

參數(shù)**kwargs查找結(jié)果如下所示:4.4.3通過查找方法選取節(jié)點(diǎn)soup.find_all(id='link3')[<aclass="sister"href="/tillie"id="link3">Tillie</a>]如果我們要查找的節(jié)點(diǎn)名稱為class,由于class屬于Python中的關(guān)鍵字,所以需要在class的后面加上一個(gè)下畫線,示例代碼如下所示。

參數(shù)**kwargs查找結(jié)果如下所示:4.4.3通過查找方法選取節(jié)點(diǎn)soup.find_all("p",class_="title")[<pclass="title"><b>TheDormouse'sstory</b></p>]掌握BeautifulSoup中選取節(jié)點(diǎn)的方式,能夠使用CSS選擇器選取節(jié)點(diǎn)學(xué)習(xí)目標(biāo)4.4.4通過CSS選擇器選取節(jié)點(diǎn)CSS選擇器,又稱CSS屬性選擇器,它是選擇需設(shè)置樣式的元素的模式,這種模式指定了樣式作用于網(wǎng)頁頁面中的哪些元素,可以使用CSS對(duì)HTML頁面中的元素進(jìn)行一對(duì)一、一對(duì)多或多對(duì)一的控制。CSS選擇器有許多種類,其中常用的CSS選擇器有類別選擇器、元素選擇器、ID選擇器和屬性選擇器,關(guān)于這4種選擇器的介紹如下。4.4.4通過CSS選擇器選取節(jié)點(diǎn)類別選擇器:根據(jù)類名選擇元素,類名前面用“.”進(jìn)行標(biāo)注。例如,.intro表示選擇包含class="intro"的所有元素。元素選擇器:根據(jù)元素名稱選擇元素。例如,p表示選擇所有<p>元素ID選擇器:根據(jù)特定ID選擇元素,ID前面加上“#”進(jìn)行標(biāo)注。例如,#link1表示選擇特定ID的值為link1的元素。屬性選擇器:根據(jù)元素的屬性選擇元素,屬性必須用中括號(hào)進(jìn)行包裹,它既可以是標(biāo)準(zhǔn)屬性,也可以是自定義屬性。例如,[target=_blank]表示選擇包含target="_blank"的所有元素。除此之外,這些選擇器還可以組合使用,它們之間一般以空格進(jìn)行分隔。不過,對(duì)于元素選擇器和屬性選擇器來說,如果這兩個(gè)選擇器屬于同一節(jié)點(diǎn),那么兩者在組合使用時(shí)不需要加空格。例如,a[href="/elsie"]。4.4.4通過CSS選擇器選取節(jié)點(diǎn)select(self,selector,namespaces=None,limit=None,**kwargs)為方便開發(fā)者在bs4庫(kù)中使用CSS選擇器,bs4庫(kù)的BeautifulSoup類中提供了一個(gè)select()方法,該方法會(huì)根據(jù)CSS選擇器指定的模式選擇目標(biāo)節(jié)點(diǎn),并將選到的節(jié)點(diǎn)存放到列表中。select()方法中的selector參數(shù)表示CSS選擇器,支持字符串類型的值。4.4.4通過CSS選擇器選取節(jié)點(diǎn)調(diào)用select()方法時(shí)可以傳入一個(gè)類別選擇器,通過指定的類名查找目標(biāo)節(jié)點(diǎn)。例如,使用soup對(duì)象調(diào)用select()方法查找類名稱為sister的所有元素,代碼如下。

通過類別選擇器查找元素查找結(jié)果如下所示:soup.select('.sister')[<aclass="sister"href="/elsie"id="link1">Elsie</a>,<aclass="sister"href="/lacie"id="link2">Lacie</a>,<aclass="sister"href="/tillie"id="link3">Tillie</a>]4.4.4通過CSS選擇器選取節(jié)點(diǎn)調(diào)用select()方法時(shí)可以傳入一個(gè)元素選擇器,通過元素的名稱查找目標(biāo)元素。例如,使用soup對(duì)象調(diào)用select()方法查找所有名稱為title的元素,代碼如下。

通過元素選擇器查找元素查找結(jié)果如下所示:soup.select("title")[<title>TheDormouse'sstory</title>]4.4.4通過CSS選擇器選取節(jié)點(diǎn)調(diào)用select()方法時(shí)可以傳入一個(gè)ID選擇器,通過特定的ID名稱查找目標(biāo)元素。例如,使用soup對(duì)象調(diào)用select()方法查找ID名稱為link1的元素,代碼如下。

通過ID選擇器查找元素soup.select("#link1")[<aclass="sister"href="/elsie"id="link1">Elsie</a>]4.4.4通過CSS選擇器選取節(jié)點(diǎn)查找結(jié)果如下所示:調(diào)用select()方法時(shí)可以傳入一個(gè)屬性選擇器,通過指定的屬性查找目標(biāo)元素。例如,使用soup對(duì)象調(diào)用select()方法查找屬性名稱為href、值為"/elsie"的元素,代碼如下所示。

通過屬性選擇器查找元素查找結(jié)果如下所示:soup.select('[href="/elsie"]')[<aclass="sister"href="/elsie"id="link1">Elsie</a>]4.4.4通過CSS選擇器選取節(jié)點(diǎn)調(diào)用select()方法時(shí)可以傳入組合的多個(gè)選擇器,通過指定的類名、元素名稱、ID或?qū)傩圆檎夷繕?biāo)元素。例如,使用soup對(duì)象調(diào)用select()方法查找ID值為"link1"元素<a>,代碼如下所示。

通過組合的多個(gè)選擇器查找元素查找結(jié)果如下所示:soup.select('a#link1')[<aclass="sister"href="/elsie"id="link1">Elsie</a>]4.4.4通過CSS選擇器選取節(jié)點(diǎn)此時(shí)可以遍歷上面的列表,并調(diào)用get_text()方法獲取元素的文本,代碼如下所示。forelementinsoup.select('a[href="/elsie"]'):print(element.get_text())#獲取節(jié)點(diǎn)的內(nèi)容輸出ElsieJsonPath與jsonpath模塊4.54.5JSONPath與jsonpath模塊除HTML和XML外,網(wǎng)頁的數(shù)據(jù)格式還有JSON。JSON是一種被廣泛使用的結(jié)構(gòu)化數(shù)據(jù)的格式,它具有清晰的層次結(jié)構(gòu),可以采用類似JSONPath表達(dá)式的方式定位目標(biāo)對(duì)象。Python中提供了支持JSONPath的模塊jsonpath。熟悉JSONPath的語法,能夠熟練地編寫JSONPath的表達(dá)式學(xué)習(xí)目標(biāo)4.5.1JSONPath語法4.5.1JSONPath語法JSONPath可以看作定位目標(biāo)對(duì)象位置的語言,適用于JSON文檔。JSONPath與JSON關(guān)系相當(dāng)于XPath與XML關(guān)系,JSONPath參照XPath的路徑表達(dá)式,通過表達(dá)式度目標(biāo)對(duì)象定位。JSONPath遵循相對(duì)簡(jiǎn)單的語法,采用了更加友好的表達(dá)式形式JSONPathXPath說明$/選取根對(duì)象/根節(jié)點(diǎn)@.選取當(dāng)前對(duì)象/當(dāng)前節(jié)點(diǎn).或[]/選取下級(jí)對(duì)象/子節(jié)點(diǎn)不支持..選取父節(jié)點(diǎn),JSONPath不支持..//選取所有符合條件的對(duì)象/節(jié)點(diǎn)**選取所有對(duì)象/節(jié)點(diǎn)不支持@選取屬性節(jié)點(diǎn),由于JSON沒有屬性,所以JSONPath不支持[][]下標(biāo)運(yùn)算符[,]|聯(lián)合運(yùn)算符?()[]支持過濾操作()不支持支持表達(dá)式計(jì)算不支持()支持分組,JSONPath不支持4.5.1JSONPath語法以一個(gè)JSON文檔為例,為大家演示使用JSONPath語法選取JSON文檔的對(duì)象。JSON文檔的具體內(nèi)容如下。{"store":{"book":[{"category":"reference","author":"NigelRees","title":"SayingsoftheCentury","price":8.95},{"category":"fiction","author":"J.R.R.Tolkien","title":"TheLordoftheRings","isbn":"0-394-19394-8","price":22.99}],"bicycle":{"color":"red","price":19.95}}}4.5.1JSONPath語法通過JSONPath的表達(dá)式選取節(jié)點(diǎn)的示例代碼如下所示。#選取bicycle對(duì)象中字段color的值$.store.bicycle.color#選取books列表中包含的所有對(duì)象$.store.book[*]#選取books列表的第一個(gè)對(duì)象$.store.book[0]#選取books列表中所有對(duì)象對(duì)應(yīng)的字段title的值$.store.book[*].title#選取books列表中字段category的值為fiction的所有對(duì)象$.store.book[?(@.category=='fiction')]#選取books列表中所有price小于10的對(duì)象$.store.book[?(@.price<10)]#選取books列表中所有含有isb的對(duì)象$.store.book[?(@.isb)]掌握jsonpath模塊的用法,能夠靈活運(yùn)用jsonpath模塊解析JSON文檔學(xué)習(xí)目標(biāo)4.5.2jsonpath模塊的使用jsonpath是一個(gè)解析JSON文檔的模塊,它可以通過JSONPath的表達(dá)式從JSON文檔中提取需要的數(shù)據(jù)。jsonpath支持多種語言的實(shí)現(xiàn)版本,包括Python、JavaScript、PHP和Java。值得一提的是,我們需要使用pip工具在本機(jī)環(huán)境中安裝jsonpath,具體的安裝命令為“pipinstalljsonpath”,安裝完成后便可以使用jsonpath解析JSON文檔。4.5.2jsonpath模塊的使用jsonpath模塊中提供了一個(gè)重要的函數(shù)jsonpath()。jsonpath()函數(shù)會(huì)根據(jù)JSONPath的表達(dá)式定位目標(biāo)對(duì)象,并從目標(biāo)對(duì)象中提取想要的數(shù)據(jù)。4.5.2jsonpath模塊的使用jsonpath(obj,expr,result_type='VALUE',debug=0,use_eval=True)obj:必選參數(shù),表示需要解析的對(duì)象,該參數(shù)支持的取值為Python對(duì)象。expr:必選參數(shù),表示JSONPath表達(dá)式的字符串。result_type:可選參數(shù),表示結(jié)果是匹配值或表達(dá)式,該參數(shù)支持兩種取值"VALUE"|"PATH"。jsonpath()函數(shù)會(huì)返回包含解析后的結(jié)果的列表。為了幫助大家更好地理解,接下來,以4.5.1節(jié)的JSON文檔為例,使用jsonpath()函數(shù)根據(jù)表達(dá)式選取目標(biāo)對(duì)象。假設(shè)變量book_json中保存了4.5.1小節(jié)的JSON文檔,需要將book_json轉(zhuǎn)換為Python對(duì)象,示例代碼如下。4.5.2jsonpath模塊的使用importjsonimportjsonpathbook_json="""JSON文檔字符串"""books=json.loads(book_json)上述示例中,loads()函數(shù)是json模塊的函數(shù),用于將JSON格式的字符串轉(zhuǎn)換為Python對(duì)象。經(jīng)過上述操作后,變量books已經(jīng)保存了JSON字符串轉(zhuǎn)換后的Python對(duì)象。選取bicycle對(duì)象中字段color的值,示例代碼如下。4.5.2jsonpath模塊的使用json_expression="$.store.bicycle.color"result=jsonpath.jsonpath(books,json_expression)print(result)運(yùn)行代碼,結(jié)果如下所示。['red']選取books列表中包含的所有對(duì)象,示例代碼如下。4.5.2jsonpath模塊的使用json_expression="$.store.book[*]"result=jsonpath.jsonpath(books,json_expression)print(result)運(yùn)行代碼,結(jié)果如下所示。[{'category':'reference','author':'NigelRees','title':'SayingsoftheCentury','price':8.95},{'category':'fiction','author':'J.R.R.Tolkien','title':'TheLordoftheRings','isbn':'0-394-19394-8','price':22.99}]選取books列表的第一個(gè)對(duì)象,示例代碼如下。4.5.2jsonpath模塊的使用json_expression="$.store.book[0]"result=jsonpath.jsonpath(books,json_expression)print(result)運(yùn)行代碼,結(jié)果如下所示。[{'category':'reference','author':'NigelRees','title':'SayingsoftheCentury','price':8.95}]選取books列表中所有對(duì)象的屬性title的值,示例代碼如下。4.5.2jsonpath模塊的使用json_expression="$.store.book[*].title"result=jsonpath.jsonpath(books,json_expression)print(result)運(yùn)行代碼,結(jié)果如下所示。['SayingsoftheCentury','TheLordoftheRings']選取books列表中屬性category的值為fiction的所有對(duì)象,示例代碼如下。4.5.2jsonpath模塊的使用json_expression="$.store.book[?(@.category=='fiction')]"result=jsonpath.jsonpath(books,json_expression)print(result)運(yùn)行代碼,結(jié)果如下所示。[{'category':'fiction','author':'J.R.R.Tolkien','title':'TheLordoftheRings','isbn':'0-394-19394-8','price':22.99}]選取books列表中所有price的值小于10的對(duì)象,示例代碼如下。4.5.2jsonpath模塊的使用json_expression="$.store.book[?(@.price<10)]"result=jsonpath.jsonpath(books,json_expression)print(result)運(yùn)行代碼,結(jié)果如下所示。[{'category':'reference','author':'NigelRees','title':'SayingsoftheCentury','price':8.95}]選取books列表中所有包含isbn的對(duì)象,示例代碼如下所示。4.5.2jsonpath模塊的使用json_expression="$.store.book[?(@.isbn)]"result=jsonpath.jsonpath(books,json_expression)print(result)運(yùn)行代碼,結(jié)果如下所示。[{'category':'fiction','author':'J.R.R.Tolkien','title':'TheLordoftheRings','isbn':'0-394-19394-8','price':22.99}]多學(xué)一招json模塊可以輕松地將Python對(duì)象編碼轉(zhuǎn)換為JSON格式的數(shù)據(jù),也可以將JSON格式的數(shù)據(jù)解碼轉(zhuǎn)換為Python對(duì)象,前者對(duì)應(yīng)的操作過程稱為序列化,后者對(duì)應(yīng)的操作過程稱為反序列化。json模塊json模塊中主要提供了4個(gè)函數(shù),分別是loads()、load()、dumps()和dump(),其中l(wèi)oads()和load()函數(shù)用于實(shí)現(xiàn)反序列化的功能,dumps()和dump()函數(shù)用于實(shí)現(xiàn)序列化的功能。多學(xué)一招l(wèi)oads()和load()函數(shù)都可以將JSON格式的數(shù)據(jù)轉(zhuǎn)換為Python對(duì)象,JSON數(shù)據(jù)類型向Python對(duì)象類型轉(zhuǎn)換的對(duì)照表如下所示。json模塊JSON數(shù)據(jù)類型說明Python對(duì)象類型說明object對(duì)象dict字典array數(shù)組list列表string字符串str字符串number(int)數(shù)字型int整型number(real)數(shù)字型float浮點(diǎn)型true布爾型True布爾型false布爾型False布爾型null空None空多學(xué)一招l(wèi)oads()和load()函數(shù)作用相同,都可以實(shí)現(xiàn)反序列化操作,但兩者的用法有著一些區(qū)別,loads()函數(shù)需要接收字符串形式的JSON數(shù)據(jù),而load()函數(shù)需要接收文件形式的JSON數(shù)據(jù)。json模塊importjson#將JSON對(duì)象轉(zhuǎn)換為Python字典result_dict=json.loads('{"city":"北京","name":"小明"}')print(result_dict)result_dict=json.load(open("dict_str.json"))print(result_dict)多學(xué)一招dumps()和dump()函數(shù)都可以將Python類型的對(duì)象轉(zhuǎn)換為JSON格式的數(shù)據(jù),Python對(duì)象類型向JSON數(shù)據(jù)類型轉(zhuǎn)換的對(duì)照表如下所示。json模塊Python對(duì)象類型說明JSON數(shù)據(jù)類型說明dict字

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論