《Python大數(shù)據(jù)基礎(chǔ)》課件-3.Python數(shù)據(jù)獲取_第1頁(yè)
《Python大數(shù)據(jù)基礎(chǔ)》課件-3.Python數(shù)據(jù)獲取_第2頁(yè)
《Python大數(shù)據(jù)基礎(chǔ)》課件-3.Python數(shù)據(jù)獲取_第3頁(yè)
《Python大數(shù)據(jù)基礎(chǔ)》課件-3.Python數(shù)據(jù)獲取_第4頁(yè)
《Python大數(shù)據(jù)基礎(chǔ)》課件-3.Python數(shù)據(jù)獲取_第5頁(yè)
已閱讀5頁(yè),還剩90頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡(jiǎn)介

爬蟲和爬蟲的構(gòu)成HTML和網(wǎng)絡(luò)基礎(chǔ)解析HTML文件獲取數(shù)據(jù)從網(wǎng)站獲取網(wǎng)頁(yè)urllib、requests直接獲取SeleniumScray爬蟲框架目錄1.1、獲取數(shù)據(jù)的重要性數(shù)據(jù)是大數(shù)據(jù)處理的基礎(chǔ),獲取數(shù)據(jù)是數(shù)據(jù)處理和分析的第一步。1.2、如何獲取數(shù)據(jù)(1)從一些開源的網(wǎng)站上直接下載相關(guān)數(shù)據(jù)集,比如國(guó)外的kaggle和國(guó)內(nèi)的阿里天池。(2)利用相關(guān)技術(shù)從網(wǎng)頁(yè)中抓取相關(guān)數(shù)據(jù),比如爬蟲,然后利用獲得的數(shù)據(jù)進(jìn)行相關(guān)數(shù)據(jù)分析工作。一、如何獲取數(shù)據(jù)/

數(shù)據(jù)集,例子程序,大數(shù)據(jù)處理競(jìng)賽圖1阿里天池官網(wǎng)2.1、爬蟲的定義如果將互聯(lián)網(wǎng)比作一張大網(wǎng),爬蟲就像是在網(wǎng)上爬行的蜘蛛。把每個(gè)頁(yè)面比作是一個(gè)個(gè)節(jié)點(diǎn),網(wǎng)絡(luò)爬蟲訪問(wèn)了該頁(yè)面并獲取了信息就相當(dāng)于爬過(guò)了該節(jié)點(diǎn)。簡(jiǎn)單來(lái)講,爬蟲就是一段自動(dòng)抓取互聯(lián)網(wǎng)信息的程序,從互聯(lián)網(wǎng)抓取特定的信息

。二、什么是爬蟲圖2爬蟲定義爬蟲的組成爬蟲主要由4個(gè)模塊組成,包括爬蟲調(diào)度器,URL管理器(URL隊(duì)列),HTML下載器和HTML解析器。爬蟲調(diào)度器負(fù)責(zé)從URL管理器中取出需下載的URL,并啟動(dòng)HTML下載器。HTML下載器訪問(wèn)對(duì)應(yīng)的URL并將獲取的內(nèi)容存在本地或直接傳給HTML解析器處理。HTML解析器分析獲取的HTML文件內(nèi)容,從中提取數(shù)據(jù)存入本地文件系統(tǒng)或數(shù)據(jù)庫(kù)中,并且從中提取需抓取的其他數(shù)據(jù)的URL放入U(xiǎn)RL管理器中。HTML下載和HTML解析是爬蟲設(shè)計(jì)的核心技術(shù)。圖3爬蟲的組成3.1、HTML頁(yè)面的獲取與響應(yīng)瀏覽器和服務(wù)器之間采用的是HTTP(HyperTextTransferProtocol)協(xié)議傳輸網(wǎng)頁(yè)。傳輸?shù)膬?nèi)容不局限于文本,圖片,音頻和各種js程序片段都可以通過(guò)這個(gè)協(xié)議傳輸。其傳輸過(guò)程如圖所示。三、HTML基本知識(shí)圖4HTTP傳輸過(guò)程選擇開發(fā)者工具后,在瀏覽器下方會(huì)出現(xiàn)開發(fā)者工具的選項(xiàng)。選中網(wǎng)絡(luò)后,在地址欄輸入百度的網(wǎng)址,在網(wǎng)絡(luò)選項(xiàng)卡中可以看到瀏覽器會(huì)發(fā)出幾十條請(qǐng)求。第一條是html文件,是百度的首頁(yè),其他的包括css樣式表,png或jpeg的圖片,以及js腳本文件。開發(fā)者工具中的網(wǎng)絡(luò)工具詳細(xì)展示了瀏覽器和服務(wù)器之間的交互過(guò)程。從列表中可以看到訪問(wèn)的狀態(tài),訪問(wèn)方式,訪問(wèn)域名和文件,以及文件的類型,大小,傳輸時(shí)間等信息。利用火狐瀏覽器觀察網(wǎng)絡(luò)通信過(guò)程圖5通信過(guò)程單次請(qǐng)求請(qǐng)求方式常見的有GET,POST兩種類型,另外還有HEAD,PUT,DELETE,OPTIONS等。請(qǐng)求URLURL的全名是統(tǒng)一資源定位符。網(wǎng)絡(luò)上的一切資源都是位于服務(wù)器的某一個(gè)位置,而URL就是通知瀏覽器去哪里獲取這些資源請(qǐng)求頭請(qǐng)求頭(header)就是告訴服務(wù)器瀏覽器的版本,主機(jī)位置,緩存等,包括但不限于User-gaget,Host,Cookies等信息。服務(wù)器有時(shí)會(huì)檢查請(qǐng)求頭的內(nèi)容,拒絕爬蟲的訪問(wèn)等。通常需要在訪問(wèn)時(shí)添加請(qǐng)求頭信息,保證請(qǐng)求合法。請(qǐng)求體請(qǐng)求時(shí)包含的額外數(shù)據(jù),如POST請(qǐng)求需要輸入的表單數(shù)據(jù),一般用于登錄,表單提交等。3.2、單次請(qǐng)求與響應(yīng)(1)單個(gè)文件的獲取是發(fā)起請(qǐng)求(Request),并獲取服務(wù)器響應(yīng)(Response)的過(guò)程。瀏覽器將包括URL在內(nèi)的信息發(fā)送給對(duì)應(yīng)的服務(wù)器,這個(gè)電文被稱為Request。服務(wù)器收到瀏覽器發(fā)送的消息后,根據(jù)瀏覽器發(fā)送消息的內(nèi)容做響應(yīng)的處理,并將結(jié)果發(fā)送給瀏覽器,這個(gè)電文被稱為Response。Request電文主要包括請(qǐng)求方式,請(qǐng)求網(wǎng)址,請(qǐng)求頭和請(qǐng)求體四個(gè)部分。且請(qǐng)求電文包含的內(nèi)容如下:?jiǎn)未雾憫?yīng)(2)從服務(wù)器獲取網(wǎng)頁(yè)的請(qǐng)求方式通常為GET和POST。GET方式一般用于獲取或者查詢資源信息,一般不需要傳入復(fù)雜的參數(shù),響應(yīng)速度快。POST方式可以在請(qǐng)求體中增加自定義的參數(shù),并給出具體的值。這種方式常用于網(wǎng)站登錄和表單提交等場(chǎng)景。瀏覽器向服務(wù)器發(fā)出請(qǐng)求后,服務(wù)器就會(huì)返回一個(gè)響應(yīng)(response)電文。響應(yīng)電文的內(nèi)容如下:響應(yīng)狀態(tài)用于表示請(qǐng)求的結(jié)果,如200代表成功,404找不到頁(yè)面,502服務(wù)器錯(cuò)誤等響應(yīng)頭如內(nèi)容類型,內(nèi)容長(zhǎng)度,服務(wù)器信息,設(shè)置Cookie等等響應(yīng)體其實(shí)就是網(wǎng)頁(yè)源代碼,也就是用于解析數(shù)據(jù)的部分利用火狐瀏覽器查看請(qǐng)求內(nèi)容我們首先打開火狐瀏覽器的開發(fā)者模式,然后在地址欄中輸入百度的網(wǎng)址。從請(qǐng)求來(lái)看,火狐瀏覽器增加了很多請(qǐng)求頭,請(qǐng)求的方法是GET。從響應(yīng)來(lái)看,返回的狀態(tài)為200,返回的內(nèi)容是一個(gè)html文件。圖6查看請(qǐng)求內(nèi)容利用火狐瀏覽器查看響應(yīng)內(nèi)容點(diǎn)擊“響應(yīng)”,就可以查看到本次請(qǐng)求從服務(wù)器端返回的響應(yīng)內(nèi)容。從圖中可以看出,當(dāng)利用瀏覽器請(qǐng)求百度時(shí),服務(wù)器端返回給客戶端百度首頁(yè)的HTML源碼,當(dāng)瀏覽器接收到該響應(yīng)內(nèi)容之后,就會(huì)對(duì)源碼進(jìn)行解析,并進(jìn)行渲染,就會(huì)得到我們看到的百度首頁(yè)。圖7查看響應(yīng)內(nèi)容HTML網(wǎng)頁(yè)內(nèi)容和結(jié)構(gòu)3.3、HTML網(wǎng)頁(yè)內(nèi)容和結(jié)構(gòu)HTML(HyperTextMarkupLanguage),即超文本標(biāo)記語(yǔ)言,描述了網(wǎng)頁(yè)的結(jié)構(gòu)?,F(xiàn)在的網(wǎng)頁(yè)一般都不是由單一的HTML文件組成。除了HTML文件以及其中引用的圖片外,通常還會(huì)用到控制頁(yè)面顯示狀態(tài)的層疊樣式表CSS和javascript腳本。圖8HTML網(wǎng)頁(yè)內(nèi)容HTML解析的目的是從頁(yè)面中獲取數(shù)據(jù)和URL列表,一般可以用正則表達(dá)式提取網(wǎng)頁(yè)的信息,但是利用正則表達(dá)式的方式提取信息,顯得格外麻煩并且容易出錯(cuò)。在Python中,第三方的BeautifulSoup,pyquery和lxml等庫(kù)都可以提取網(wǎng)頁(yè)信息。四、HTML頁(yè)面解析正則表達(dá)式(RegularExpression)是一段字符串,它可以表示一段有規(guī)律的信息。Python自帶一個(gè)正則表達(dá)式模塊,通過(guò)這個(gè)模塊可以查找、提取、替換一段有規(guī)律的信息。在程序開發(fā)中,要讓計(jì)算機(jī)程序從一大段文本中找到需要的內(nèi)容,就可以使用正則表達(dá)式來(lái)實(shí)現(xiàn),比如對(duì)于URL來(lái)說(shuō),可以使用[a-zA-z]+://[^\s]*來(lái)進(jìn)行匹配。使用正則表達(dá)式有如下步驟。(1)尋找規(guī)律。(2)使用正則符號(hào)表示規(guī)律。(3)提取信息。4.1、使用正則表達(dá)式提取信息Python自1.5版本起增加了re模塊,它提供Perl風(fēng)格的正則表達(dá)式模式。re模塊使Python語(yǔ)言擁有全部的正則表達(dá)式功能,如果需要使用該模塊,需要引入該模塊:importre。re模塊的主要函數(shù)如下表所示。4.1.1在Python中使用正則表達(dá)式函數(shù)名功能re.match()re.match()嘗試從字符串的起始位置匹配一個(gè)模式,成功返回一個(gè)Match對(duì)象。如果不是起始位置匹配成功的話,函數(shù)就返回none。re.search()re.search()掃描整個(gè)字符串并返回第一個(gè)成功匹配的Match對(duì)象。re.sub()re.sub()用于替換字符串中的匹配項(xiàng)pile()compile()函數(shù)用于編譯正則表達(dá)式,生成一個(gè)正則表達(dá)式(Pattern)對(duì)象,供match()和search()這兩個(gè)函數(shù)使用。re.finditer()在字符串中找到正則表達(dá)式所匹配的所有子串,并把它們作為一個(gè)迭代器返回。re.findall()在字符串中找到正則表達(dá)式所匹配的所有子串,并返回一個(gè)列表,如果沒(méi)有找到匹配的,則返回空列表。1.點(diǎn)號(hào)“.”

一個(gè)點(diǎn)號(hào)可以代替除了換行符以外的任何一個(gè)字符,包括但不限于英文字母、數(shù)字、漢字、英文標(biāo)點(diǎn)符號(hào)和中文標(biāo)點(diǎn)符號(hào)。2.星號(hào)“*”

一個(gè)星號(hào)可以表示它前面的一個(gè)子表達(dá)式(普通字符、另一個(gè)或幾個(gè)正則表達(dá)式符號(hào))0次到無(wú)限次。3.問(wèn)號(hào)“?”

問(wèn)號(hào)表示它前面的子表達(dá)式0次或者1次。注意,這里的問(wèn)號(hào)是英文問(wèn)號(hào)。

4.反斜杠“\”

反斜杠在正則表達(dá)式里面不能單獨(dú)使用,甚至在整個(gè)Python里都不能單獨(dú)使用。反斜杠需要和其他的字符配合使用來(lái)把特殊符號(hào)變成普通符號(hào),把普通符號(hào)變成特殊符號(hào)。5.?dāng)?shù)字“\d”

正則表達(dá)式里面使用“\d”來(lái)表示一位數(shù)字。為什么要用字母d呢?因?yàn)閐是英文“digital(數(shù)字)”的首字母。

再次強(qiáng)調(diào)一下,“\d”雖然是由反斜杠和字母d構(gòu)成的,但是要把“\d”看成一個(gè)正則表達(dá)式符號(hào)整體。

6.小括號(hào)“()”

小括號(hào)可以把括號(hào)里面的內(nèi)容提取出來(lái)。4.1.2正則表達(dá)式的基本符號(hào)

反斜杠不僅可以把特殊符號(hào)變成普通符號(hào),還可以把普通符號(hào)變成特殊符號(hào)。例如“n”只是一個(gè)普通的字母,但是“\n”代表?yè)Q行符。在Python開發(fā)中,經(jīng)常遇到的轉(zhuǎn)義字符,如下表所示。特殊符號(hào)字符描述\n匹配一個(gè)換行符。\s匹配任何空白字符,包括空格、制表符、換頁(yè)符等等。等價(jià)于[\f\n\r\t\v]。注意Unicode正則表達(dá)式會(huì)匹配全角空格符。\S匹配任何非空白字符。\t匹配一個(gè)制表符。\{匹配{。除此之外小括號(hào),中括號(hào)的匹配也需要轉(zhuǎn)義符。(1)re.match函數(shù):re.match(pattern,string,flags=0)參數(shù):pattern:匹配的正則表達(dá)式string:要匹配的字符串flages:標(biāo)志位,可選參數(shù),用于控制正則表達(dá)式的匹配方式,如:是否區(qū)分大小寫,多行匹配等。(2)re.search()函數(shù):re.search(pattern,string,flags=0)參數(shù):和re.match()函數(shù)相同(re.match()只匹配字符串的開始,如果字符串開始不符合正則表達(dá)式,則匹配失敗,函數(shù)返回None;而re.search()匹配整個(gè)字符串,直到找到一個(gè)匹配)(3)re.sub()函數(shù):re.sub(pattern,repl,string,count=0,flags=0)參數(shù):pattern:匹配的正則表達(dá)式repl:被替換的字符串(既可以是字符串,也可以是函數(shù))string:要匹配的字符串count:匹配的次數(shù),默認(rèn)是全部替換flags:標(biāo)志位,可選參數(shù),具體用法同re.match()函數(shù)詳解(1/2)(4)pile()函數(shù):pile(pattern[,flags])參數(shù):pattern:一個(gè)字符串形式的正則表達(dá)式flags:可選,表示匹配模式,用法同re.match()函數(shù)。(5)re.finditer()函數(shù)語(yǔ)法格式:re.finditer(pattern,string,flags=0)參數(shù):用法同re.match()函數(shù)

(6)re.findall()函數(shù)語(yǔ)法格式:re.findall(pattern,string,flags=0)參數(shù):用法同re.match()函數(shù)(match()和search()函數(shù)是匹配一次,而findall()函數(shù)匹配所有)函數(shù)詳解(2/2)在re模塊中的函數(shù)中基本上都會(huì)有一個(gè)flag參數(shù),該參數(shù)是一個(gè)可選參數(shù),指定了相關(guān)匹配控制模式。該參數(shù)的可選參數(shù)如表所示。在

Python

3.6

之后,以前的

re.S

等等的

flag

全部轉(zhuǎn)移到

RegexFlag

中了,所以有時(shí)候要改變用法

re.S

改寫成

re.RegexFlag.SFlag參數(shù)例1:使用正則表達(dá)式獲取<tr></tr>標(biāo)簽之間的數(shù)據(jù)(ReTest01.py)<tr>標(biāo)簽是位于<table>標(biāo)簽內(nèi)的,其代表表格中的一行,<tr>標(biāo)簽中還會(huì)包括<td>標(biāo)簽,其代表表格中的一個(gè)單元格,因此要獲取<tr>標(biāo)簽中的內(nèi)容,必須依次獲取<tr>中的內(nèi)容,然后在獲取<td>中的內(nèi)容,同時(shí),對(duì)于一個(gè)表格來(lái)說(shuō),還會(huì)有表頭,因此可以通過(guò)獲取<th>標(biāo)簽,來(lái)獲取表頭內(nèi)容。例1程序運(yùn)行結(jié)果:<th>西北工業(yè)大學(xué)</th><td>計(jì)算機(jī)學(xué)院</td>西北工業(yè)大學(xué)計(jì)算機(jī)學(xué)院例2:獲取超鏈接<ahref=..></a>之間內(nèi)容(ReTest02.py)網(wǎng)頁(yè)中的超鏈接常常包含著一些重要的信息,同時(shí)還包含著超鏈接地址,因此,獲取網(wǎng)頁(yè)中的超鏈接地址顯得格外重要。要獲取網(wǎng)頁(yè)中的超鏈接部分,就必須通過(guò)尋找<ahref>標(biāo)簽來(lái)獲取。例2程序運(yùn)行結(jié)果:西北工業(yè)大學(xué)西北工業(yè)大學(xué)計(jì)算機(jī)學(xué)院//XPath(XMLPath)是一種查詢語(yǔ)言,它能在XML(ExtensibleMarkupLanguage,可擴(kuò)展標(biāo)記語(yǔ)言)和HTML的樹狀結(jié)構(gòu)中尋找節(jié)點(diǎn)。在XPath中,有七種類型的節(jié)點(diǎn)(Node):元素、屬性、文本、命名空間、處理指令、注釋以及文檔(根)節(jié)點(diǎn)。在Python中,為了使用XPath,需要安裝一個(gè)第三方庫(kù)lxml:pipinstalllxml4.2使用XPath提取信息一個(gè)簡(jiǎn)單的例子(Xpathexample.html)文檔中的節(jié)點(diǎn):<html>(文檔節(jié)點(diǎn))<title>西北工業(yè)大學(xué)</title>(元素節(jié)點(diǎn))href=""(屬性節(jié)點(diǎn))圖9Xpathexample.htmlHTML文件中的節(jié)點(diǎn)可以組成一棵樹。節(jié)點(diǎn)之間的關(guān)系包括父子,兄弟等。包含在一個(gè)節(jié)點(diǎn)內(nèi)容的節(jié)點(diǎn)稱為該節(jié)點(diǎn)的子節(jié)點(diǎn)。在Xpathexample.html文件中,<body>和<head>就是<html>的子節(jié)點(diǎn)。每個(gè)節(jié)點(diǎn)有0個(gè),1個(gè)或多個(gè)子節(jié)點(diǎn)。與之對(duì)應(yīng)的是,除根節(jié)點(diǎn)外,每個(gè)節(jié)點(diǎn)都有一個(gè)父節(jié)點(diǎn)。具有相同父節(jié)點(diǎn)的節(jié)點(diǎn)互相為兄弟節(jié)點(diǎn),例子中的<body>和<head>是兄弟節(jié)點(diǎn)。HTML的樹狀結(jié)構(gòu)表達(dá)式描述nodename選取此節(jié)點(diǎn)的所有子節(jié)點(diǎn)。/從根節(jié)點(diǎn)選取。//從匹配選擇的當(dāng)前節(jié)點(diǎn)選擇文檔中的節(jié)點(diǎn),而不考慮它們的位置。.選取當(dāng)前節(jié)點(diǎn)。..選取當(dāng)前節(jié)點(diǎn)的父節(jié)點(diǎn)。@選取屬性。XPath使用路徑表達(dá)式在XML文檔中選取節(jié)點(diǎn)。節(jié)點(diǎn)是通過(guò)沿著路徑或者step來(lái)選取的。常見的路徑表達(dá)式如下表所示。Xpath表達(dá)路徑路徑表達(dá)式示例路徑表達(dá)式結(jié)果body選取body元素的所有子節(jié)點(diǎn)。/html選取根元素html。注:假如路徑起始于正斜杠(/),則此路徑始終代表到某元素的絕對(duì)路徑!body/p選取屬于html/body的子元素的所有p元素。//p選取所有p子元素,而不管它們?cè)谖臋n中的位置。body//p選擇屬于body元素的后代的所有p元素,而不管它們位于body之下的什么位置。//@href選取名為href的所有屬性。路徑表達(dá)式示例在路徑表達(dá)式中可以用謂詞(Predicates)來(lái)查找某個(gè)特定的節(jié)點(diǎn)或者包含某個(gè)指定的值的節(jié)點(diǎn)。謂語(yǔ)被嵌在方括號(hào)中,限定和它相鄰的節(jié)點(diǎn)。下表列出了XPath路徑表達(dá)式謂詞的實(shí)例。路徑表達(dá)式中使用謂詞路徑表達(dá)式結(jié)果body/p[1]選取屬于body子元素的第一個(gè)p元素。/html/body/p[last()]選取屬于body子元素的最后一個(gè)p元素。body/p[last()-1]選取屬于bookstore子元素的倒數(shù)第二個(gè)book元素。//a[@href]選取所有擁有名為href的屬性的a元素。//div[@class=”abc”]選取所有div元素,且這些元素?fù)碛兄禐閍bc的class屬性。通配符結(jié)果*匹配任何元素節(jié)點(diǎn)。@*匹配任何屬性節(jié)點(diǎn)。node()匹配任何類型的節(jié)點(diǎn)。通配符結(jié)果body/*選取bookstore元素的所有子元素。//*選取文檔中的所有元素。//a[@*]選取所有帶有屬性的a元素。使用通配符可以選取未知節(jié)點(diǎn),上面的表列出了XPath路徑表達(dá)式中的通配符,下面的表列出了使用通配符及其獲取的結(jié)果。Xpath通配符1、讀取HTML文件并獲取所有節(jié)點(diǎn)(Xpath.py)fromlxmlimportetree##讀取html內(nèi)容html=etree.parse("Xpathexample.html",etree.HTMLParser())result=etree.tostring(html)##獲取所有節(jié)點(diǎn)allnodes=html.xpath("http://*")print(allnodes)程序運(yùn)行結(jié)果:[<Elementhtmlat0x1e9dcda1088>,<Elementheadat0x1e9dcd96ac8>,<Elementmetaat0x1e9dcd96888>,<Elementtitleat0x1e9dcd96788>,<Elementbodyat0x1e9dcd963c8>,<Elementpat0x1e9dcd96688>,<Elementbat0x1e9dcd96288>,<Elementpat0x1e9dcd96308>,<Elementaat0x1e9dcd96148>,<Elementpat0x1e9dcd96648>,<Elementaat0x1e9dcd960c8>]代碼實(shí)例2、獲取指定節(jié)點(diǎn)(Xpath.py)##獲取所有p節(jié)點(diǎn)all_p=html.xpath("http://p")print(all_p)程序運(yùn)行結(jié)果:[<Elementpat0x1e9dcd96688>,<Elementpat0x1e9dcd96308>,<Elementpat0x1e9dcd96648>]代碼實(shí)例3、獲取子節(jié)點(diǎn):通過(guò)/或者//可以查找元素的子節(jié)點(diǎn)或者子孫節(jié)點(diǎn)(Xpath.py)##選擇p節(jié)點(diǎn)的所有直接a子節(jié)點(diǎn)。child_a=html.xpath("http://p/a")print(child_a)程序運(yùn)行結(jié)果:[<Elementaat0x1e9dca75848>,<Elementaat0x1e9dca75dc8>]代碼實(shí)例4、獲取父節(jié)點(diǎn):如果我們知道了子節(jié)點(diǎn),我們可以通過(guò)..的方式來(lái)獲取該子節(jié)點(diǎn)的父節(jié)點(diǎn)信息(Xpath.py)。parent_node=html.xpath('//a[@href=""]//../@class')print(parent_node)程序運(yùn)行結(jié)果:['p1']代碼實(shí)例5、獲取節(jié)點(diǎn)中的文本信息:如果想獲取節(jié)點(diǎn)中的內(nèi)容,可以通過(guò)xpath()函數(shù)中追加text()來(lái)獲取(Xpath.py)。#獲取ahref=所對(duì)應(yīng)的內(nèi)容content=html.xpath('//p/a[@href=""]/text()')print(content)程序運(yùn)行結(jié)果:['西北工業(yè)大學(xué)首頁(yè)']代碼實(shí)例BeautifulSoup是一個(gè)可以從HTML或XML文件中提取數(shù)據(jù)的Python庫(kù)。它提供一些簡(jiǎn)單的、python式的函數(shù)用來(lái)處理導(dǎo)航、搜索、修改分析樹等功能。它是一個(gè)工具箱,通過(guò)解析文檔為用戶提供需要抓取的數(shù)據(jù),因?yàn)楹?jiǎn)單,所以不需要多少代碼就可以寫出一個(gè)完整的應(yīng)用程序。BeautifulSoup自動(dòng)將輸入文檔轉(zhuǎn)換為Unicode編碼,輸出文檔轉(zhuǎn)換為utf-8編碼。BeautifulSoup已成為一個(gè)和lxml、html6lib一樣出色的python解釋器,為用戶靈活地提供不同的解析策略和強(qiáng)勁的速度。4.3使用BeautifulSoup提取信息解析器使用方法Python標(biāo)準(zhǔn)庫(kù)BeautifulSoup(markup,"html.parser")lxmlHTML解析器BeautifulSoup(markup,"lxml")lxmlXML解析器BeautifulSoup(markup,"xml")html5libBeautifulSoup(markup,"html5lib")BeautifulSoup支持Python標(biāo)準(zhǔn)庫(kù)中的HTML解析器,還支持一些第三方的解析器,其中一個(gè)是lxml,如果需要使用lxml解析器,則需要安裝lxml。另一個(gè)可供選擇的解析器是純Python實(shí)現(xiàn)的html5lib,html5lib的解析方式與瀏覽器相同。BeautifulSoup官網(wǎng)推薦使用lxml作為解析器,因?yàn)樾矢摺eautifulSoup支持的解析器如表所示。解析器BeautifulSoup將復(fù)雜HTML文檔轉(zhuǎn)換成一個(gè)復(fù)雜的樹形結(jié)構(gòu),每個(gè)節(jié)點(diǎn)都是Python對(duì)象,所有對(duì)象可以歸納為4種:Tag,NavigableString,BeautifulSoup,Comment。(1)Tag對(duì)象Tag對(duì)象與XML或HTML原生文檔中的tag相同。一個(gè)Tag可能包含多個(gè)字符串或其它的Tag,這些都是這個(gè)Tag的子節(jié)點(diǎn)。BeautifulSoup提供了許多操作和遍歷子節(jié)點(diǎn)的屬性。例(BeautifulSoup01.py):frombs4importBeautifulSoupsoup=BeautifulSoup('<bclass="boldest">西北工業(yè)大學(xué)</b>')tag=soup.bprint(type(tag))程序運(yùn)行結(jié)果:<class'bs4.element.Tag'>對(duì)象的種類Tag對(duì)象有很多屬性,其中最重要的兩個(gè)屬性為:name和attributes。A、每一個(gè)Tag對(duì)象都有一個(gè)name,可以通過(guò).name的方式獲取Tag對(duì)象的name。

Eg:print()#將打印出bB、也可以改變Tag對(duì)象的name屬性,如果改變了Tag對(duì)象的name,將影響所有通過(guò)當(dāng)前BeautifulSoup對(duì)象生成的HTML文檔。Eg:="p"print(tag)程序?qū)⒋蛴〕?lt;pclass="boldest">西北工業(yè)大學(xué)</p>C、attributes屬性指的是Tag對(duì)象的屬性,一個(gè)Tag對(duì)象可能有很多個(gè)屬性。比如<bclass="boldest">有一個(gè)“class”的屬性,值為“boldest”??梢酝ㄟ^(guò).attrs來(lái)獲取屬性。Eg:print(tag.attrs)程序運(yùn)行結(jié)果:{'class':['boldest’]}從程序的返回結(jié)果可以看出,tag.attrs返回的是一個(gè)python字典,所以Tag對(duì)象的有關(guān)屬性的相關(guān)操作和對(duì)字典的操作相同。Tag對(duì)象屬性例(BeautifulSoup01.py)#獲取class屬性的值print(tag["class"])#['boldest']#修改class屬性的值tag["class"]="nwpu"#增加一個(gè)id屬性tag["id"]="1"print(tag)#<pclass="nwpu"id="1">西北工業(yè)大學(xué)</p>#刪除id屬性deltag['id']print(tag)#<pclass="nwpu">西北工業(yè)大學(xué)</p>在獲取屬性時(shí),可以通過(guò)tag.attrs['屬性值']的方式獲取,但是一般為了簡(jiǎn)單,可以簡(jiǎn)寫為tag['屬性值']。獲取class的屬性字符串常被包含在Tag對(duì)象內(nèi)。BeautifulSoup用NavigableString類來(lái)包裝Tag對(duì)象中的字符串。例(BeautifulSoup01.py):print(tag.string)#西北工業(yè)大學(xué)print(type(tag.string))#<class'bs4.element.NavigableString’>tag中包含的字符串不能編輯,但是可以被替換成其它的字符串,用replace_with()方法。例(BeautifulSoup01.py):tag.string.replace_with("西北工業(yè)大學(xué)計(jì)算機(jī)學(xué)院")print(tag)#<pclass="nwpu">西北工業(yè)大學(xué)計(jì)算機(jī)學(xué)院</p>NavigableString對(duì)象BeautifulSoup對(duì)象表示的是一個(gè)文檔的全部?jī)?nèi)容。大部分時(shí)候,可以把它當(dāng)作Tag對(duì)象。但是因?yàn)锽eautifulSoup對(duì)象并不是真正的HTML或XML的Tag,所以它沒(méi)有name和attribute屬性。但是BeautifulSoup對(duì)象包含了一個(gè)值為“[document]”的特殊屬性name。例(BeautifulSoup01.py):print(type(soup))#<class'bs4.BeautifulSoup'>print()#[document]BeautifulSoup對(duì)象Tag,NavigableString,BeautifulSoup幾乎覆蓋了html和xml中的所有內(nèi)容,但是還有一些特殊對(duì)象,比如注釋內(nèi)容。此時(shí),就要用到Comment對(duì)象。Comment對(duì)象是一個(gè)特殊類型的NavigableString對(duì)象。例(BeautifulSoup01.py):markup="<b><!--IamastudentofNWPU--></b>"soup=BeautifulSoup(markup)comment=soup.b.stringprint(type(comment))#<class'bs4.element.Comment'>print(comment)#IamastudentofNWPUComment對(duì)象1、子節(jié)點(diǎn)對(duì)于一個(gè)Tag對(duì)象,它可能包括多個(gè)字符串或者其它的Tag對(duì)象,這些都是這個(gè)Tag的子節(jié)點(diǎn),在BeautifulSoup中提供了許多操作和遍歷子節(jié)點(diǎn)的屬性。在BeautifulSoup中,如果我們需要獲取某一個(gè)Html標(biāo)簽,可以通過(guò)“soup.便簽名”的方式獲取(soup是一個(gè)BeautifulSoup對(duì)象,如soup.title)。同時(shí),Tag對(duì)象有很多的屬性,可以很方便的供用戶調(diào)用。遍歷文檔樹示例文檔(BeautifulSoup02.py)html_doc="""<html><head><title>TheDormouse'sstory</title></head><pclass="title"><b>TheDormouse'sstory</b></p><pclass="story">Onceuponatimetherewerethreelittlesisters;andtheirnameswere<ahref="/elsie"class="sister"id="link1">Elsie</a>,<ahref="/lacie"class="sister"id="link2">Lacie</a>and<ahref="/tillie"class="sister"id="link3">Tillie</a>;andtheylivedatthebottomofawell.</p><pclass="story">...</p>"""frombs4importBeautifulSoupsoup=BeautifulSoup(html_doc)示例文檔Tag的contents屬性可以將Tag的子節(jié)點(diǎn)以列表的方式輸出,通過(guò)Tag的.children生成器,可以對(duì)tag的子節(jié)點(diǎn)進(jìn)行循環(huán)。例(BeautifulSoup02.py):head_tag=soup.headprint(head_tag)#<head><title>TheDormouse'sstory</title></head>print(head_tag.contents)#[<title>TheDormouse'sstory</title>]title_tag=head_tag.contents[0]print(title_tag)#<title>TheDormouse'sstory</title>print(title_tag.contents)#["TheDormouse'sstory"]對(duì)于head_tag,它是一個(gè)Tag對(duì)象,head_tag.contents會(huì)將head_tag的子節(jié)點(diǎn)按照列表的形式列出,所以對(duì)于head_tag.contents的返回結(jié)果,其操作方式和python中的列表一致,且列表中保存的仍然是一個(gè)Tag對(duì)象。當(dāng)調(diào)用children屬性時(shí),獲取到的是一個(gè)迭代器,然后就可以通過(guò)循環(huán)的方式來(lái)遍歷迭代器中的內(nèi)容。例(BeautifulSoup02.py):forchildintitle_tag.children:print(child)#TheDormouse'sstorycontents和childrencontents和children屬性僅包含Tag的直接子節(jié)點(diǎn),例如,<head>標(biāo)簽只有一個(gè)直接子節(jié)點(diǎn)<title>。如果想要獲取所以子孫節(jié)點(diǎn)的話,可以使用descendants屬性。例(BeautifulSoup02.py):print(type(head_tag.descendants))forchildinhead_tag.descendants:print(child)程序運(yùn)行結(jié)果:<class'generator'><title>TheDormouse'sstory</title>TheDormouse'sstory從程序運(yùn)行結(jié)果可以看出,head_tag.descendants是一個(gè)generator對(duì)象,對(duì)于這個(gè)對(duì)象,可以利用for循環(huán)進(jìn)行遍歷。在給出的例子中,<head>標(biāo)簽只有一個(gè)子節(jié)點(diǎn),但是有2個(gè)子孫節(jié)點(diǎn):<head>節(jié)點(diǎn)和<head>的子節(jié)點(diǎn)<title>。descendantsParent:如果想獲取某個(gè)元素的父節(jié)點(diǎn),可以通過(guò)parent屬性來(lái)獲取。比如,在給出的文檔中,<head>標(biāo)簽是<title>標(biāo)簽的父節(jié)點(diǎn)。例(BeautifulSoup02.py):print(title_tag.parent)#<head><title>TheDormouse'sstory</title></head>一個(gè)文檔的頂層節(jié)點(diǎn),比如<html>的父節(jié)點(diǎn)是BeautifulSoup對(duì)象,對(duì)于BeautifulSoup對(duì)象的parent屬性是None。例(BeautifulSoup02.py):html_tag=soup.htmlprint(type(html_tag.parent))#<class'bs4.BeautifulSoup'>print(soup.parent)#None父節(jié)點(diǎn)和祖先節(jié)點(diǎn)Parents:通過(guò)元素的parents屬性可以遞歸得到元素的所有父輩節(jié)點(diǎn)。例(BeautifulSoup02.py):#遍歷<a>便簽到根節(jié)點(diǎn)的所有節(jié)點(diǎn)。link=soup.aprint(link)forparentinlink.parents:ifparentisNone:print(parent)else:print()程序運(yùn)行結(jié)果:<aclass="sister"href="/elsie"id="link1">Elsie</a>pbodyhtml[document]父節(jié)點(diǎn)和祖先節(jié)點(diǎn)兄弟節(jié)點(diǎn)就是當(dāng)前節(jié)點(diǎn)的同級(jí)節(jié)點(diǎn),比如“<a><b>text1</b><c>text2</c></b></a>”,因?yàn)?lt;b>標(biāo)簽和<c>標(biāo)簽是同一層:他們是同一個(gè)元素的子節(jié)點(diǎn),所以<b>和<c>可以被稱為兄弟節(jié)點(diǎn)。next_sibling和previous_sibling:在文檔樹中,使用next_sibling和previous_sibling屬性來(lái)查詢兄弟節(jié)點(diǎn)。例(BeautifulSoup02.py):sibling_soup=BeautifulSoup("<a><b>text1</b><c>text2</c></b></a>")print(sibling_soup.b.next_sibling)#<c>text2</c>print(sibling_soup.c.previous_sibling)#<b>text1</b><b>標(biāo)簽有next_sibling屬性,但是沒(méi)有previous_sibling屬性,因?yàn)?lt;b>標(biāo)簽在同級(jí)節(jié)點(diǎn)中是第一個(gè)。同理,<c>標(biāo)簽有previous_sibling屬性,卻沒(méi)有next_sibling屬性。兄弟節(jié)點(diǎn)next_siblings和previous_siblings:通過(guò)next_siblings和previous_siblings屬性可以對(duì)當(dāng)前節(jié)點(diǎn)的兄弟節(jié)點(diǎn)迭代輸出例(BeautifulSoup02.py):forsiblinginsoup.a.next_siblings:print(repr(sibling))forsiblinginsoup.find(id="link3").previous_siblings:print(repr(sibling))程序運(yùn)行結(jié)果:',\n'<aclass="sister"href="/lacie"id="link2">Lacie</a>'and\n'<aclass="sister"href="/tillie"id="link3">Tillie</a>';\nandtheylivedatthebottomofawell.''and\n'<aclass="sister"href="/lacie"id="link2">Lacie</a>',\n'<aclass="sister"href="/elsie"id="link1">Elsie</a>'Onceuponatimetherewerethreelittlesisters;andtheirnameswere\n兄弟節(jié)點(diǎn)BeautifulSoup定義了很多搜索方法,這些方法可以很方便的使我們定位到某一個(gè)標(biāo)簽,其中最重要的兩個(gè)方法就是find()和find_all()。find_all()函數(shù):find_all()方法搜索當(dāng)前tag的所有tag子節(jié)點(diǎn),并判斷是否符合過(guò)濾器的條件,過(guò)濾器可以是一個(gè)字符串、也可以是一個(gè)正則表達(dá)式、也可以是一個(gè)列表、也可以是一個(gè)布爾值,同時(shí)也可以定義為一個(gè)函數(shù),其目的就是讓find_all()函數(shù)搜索出所以符合條件的標(biāo)簽。其函數(shù)原型為:find_all(name,attrs,recursive,text,**kwargs)搜索文檔樹name參數(shù):傳入name參數(shù),可以按照節(jié)點(diǎn)的名稱進(jìn)行查詢?cè)亍ttrs參數(shù):除了根據(jù)節(jié)點(diǎn)名查詢,我么也可以傳入一些屬性來(lái)查詢。當(dāng)傳入attrs參數(shù)時(shí),參數(shù)的類型應(yīng)該是一個(gè)字典類型。recursive參數(shù):調(diào)用Tag對(duì)象的find_all()方法時(shí),BeautifulSoup會(huì)檢索當(dāng)前Tag的所有子孫節(jié)點(diǎn),如果只想搜索Tag的直接子節(jié)點(diǎn),可以使用參數(shù)recursive=False。text參數(shù):text參數(shù)可用來(lái)匹配節(jié)點(diǎn)的文本,傳入的形式可以是字符串,也可以是正則表達(dá)式對(duì)象,也可以是一個(gè)列表,也可以是一個(gè)函數(shù)。find_all()函數(shù)參數(shù)find()函數(shù)與find_all()函數(shù)用法大致相似。其函數(shù)原型為:find(name,attrs,recursive,text,**kwargs)但是find()函數(shù)只返回單個(gè)元素,也就是第一個(gè)匹配的元素,而find_all()函數(shù)返回的是所以匹配元素組成的列表。例:查找標(biāo)簽為p的第一個(gè)匹配元素(BeautifulSoup02.py)print(soup.find('p'))print(type(soup.find('p')))程序運(yùn)行結(jié)果:<pclass="title"><b>TheDormouse'sstory</b></p><class'bs4.element.Tag'>find()函數(shù)除了find_all()和find()方法,BeautifulSoup中還有其它10個(gè)用于搜索的API。其用法以及參數(shù)與find_all()和find()函數(shù)相似。find_parents()和find_parent():前者返回祖先節(jié)點(diǎn),后者返回直接父節(jié)點(diǎn)。find_next_siblings()合find_next_sibling():前者返回后面所有的兄弟節(jié)點(diǎn),后者返回后面第一個(gè)兄弟節(jié)點(diǎn)。find_previous_siblings()和find_previous_sibling():前者返回前面所有的兄弟節(jié)點(diǎn),后者返回前面第一個(gè)兄弟節(jié)點(diǎn)。find_all_next()和find_next():前者返回節(jié)點(diǎn)后所有符合條件的節(jié)點(diǎn),后者返回第一個(gè)符合條件的節(jié)點(diǎn)。find_all_previous()和find_previous():其者返回節(jié)點(diǎn)前所有符合條件的節(jié)點(diǎn),后者返回第一個(gè)符合條件的節(jié)點(diǎn)。其他搜索函數(shù)豆瓣Top250頁(yè)面部分源碼利用BeautifulSoup分析豆瓣電影榜圖10豆瓣Top250部分源碼分析對(duì)于每一個(gè)電影信息,都在一個(gè)div中,且該div的class均設(shè)置為pl2,在div標(biāo)簽中,包含了很多子標(biāo)簽,對(duì)于電影名稱包含在第一個(gè)a標(biāo)簽中,上映時(shí)間主演等信息包含在p標(biāo)簽中,每一個(gè)電影的評(píng)分包含在class為starclearfix的div標(biāo)簽的span子標(biāo)簽中,且該span子標(biāo)簽的class為p1。通過(guò)以上分析,我們就能夠清晰地掌握該html的結(jié)構(gòu),然后我們就可以通過(guò)這些特征對(duì)該html文檔進(jìn)行分析,提取出有關(guān)信息。分析代碼(douban.py)程序運(yùn)行結(jié)果:{'地久天長(zhǎng)':7.9,'綠皮書':8.9,'孟買酒店':8.4,'調(diào)音師':8.3,'雪暴':6.2,'我們':6.5,'海市蜃樓':7.8,'五尺天涯':8.0,'我的一級(jí)兄弟':8.2,'反貪風(fēng)暴4':6.0}代碼爬蟲首先要做的工作就是獲取網(wǎng)頁(yè),這里就是獲取網(wǎng)頁(yè)源代碼。源代碼里包含了網(wǎng)頁(yè)的部分有用信息,所以只要把源代碼獲取下來(lái),就可以從中提取想要的信息了。我們可以從網(wǎng)頁(yè)中抓取的數(shù)據(jù)有網(wǎng)頁(yè)文本、圖片、視頻等。Python語(yǔ)言提供了許多庫(kù)來(lái)幫助我們實(shí)現(xiàn)截取網(wǎng)頁(yè)源碼,如urllib、requests等。我們可以用這些庫(kù)來(lái)幫助我們實(shí)現(xiàn)HTTP請(qǐng)求操作,請(qǐng)求和響應(yīng)都可以用類庫(kù)提供的數(shù)據(jù)結(jié)構(gòu)來(lái)表示,得到響應(yīng)之后需要解析數(shù)據(jù)結(jié)構(gòu)中的Body部分即可,即可得到網(wǎng)頁(yè)源代碼,這樣我們就可以通過(guò)程序來(lái)實(shí)現(xiàn)獲取網(wǎng)頁(yè)的過(guò)程。使用爬蟲基本庫(kù),我們只需關(guān)心請(qǐng)求的鏈接是什么,需要傳的參數(shù)是什么,以及如何設(shè)置可選的請(qǐng)求頭就好了,不用深入到底層去了解它到底是怎樣傳輸和通信的。有了它,兩三行代碼就能夠完成一個(gè)請(qǐng)求和響應(yīng)的處理過(guò)程,得到網(wǎng)頁(yè)的內(nèi)容。五、頁(yè)面獲取urllib庫(kù)是Python內(nèi)置的HTTP請(qǐng)求庫(kù),也就是說(shuō)我們不需要額外安裝即可使用,它包含四個(gè)模塊,如表所示1、使用urllib模塊名功能urllib.request可以用來(lái)發(fā)送request和獲取request的結(jié)果urllib.error包含了urllib.request產(chǎn)生的異常urllib.parse包含了urllib.request產(chǎn)生的異urllib.robotparse用來(lái)解析頁(yè)面的robots.txt文件,很少使用使用Urllib的request模塊我們可以方便地實(shí)現(xiàn)Request的發(fā)送并得到Response。urlopen()函數(shù)原型:urllib.request.urlopen(url,data=None,[timeout,]*,cafile=None,capath=None,cadefault=False,context=None)urllib.request模塊提供了最基本的構(gòu)造HTTP請(qǐng)求的方法,利用它可以模擬瀏覽器的一個(gè)請(qǐng)求發(fā)起過(guò)程,同時(shí)它還帶有處理authenticaton(授權(quán)驗(yàn)證),redirections(重定向),cookies(瀏覽器Cookies)以及其它內(nèi)容。例:抓取百度首頁(yè)(urllib01.py):importurllib.requestresponse=urllib.request.urlopen("")print(response.read().decode("utf-8"))Reponse是一個(gè)HTTPResposne類型的對(duì)象,它主要包含的方法有read()、readinto()、getheader(name)、getheaders()、fileno()等方法和msg、version、status、reason、debuglevel、closed等屬性。發(fā)送請(qǐng)求——urlopen()Urllib.request.Request類是URL請(qǐng)求的抽象,該類的構(gòu)造方法如下:classurllib.request.Request(url,data=None,headers={},origin_req_host=None,unverifiable=False,method=None)參數(shù)詳解A.第一個(gè)參數(shù)是url,它是一個(gè)字符串類型且必須是一個(gè)有效的URL,該參數(shù)是一個(gè)必須參數(shù)。B.第二個(gè)參數(shù)data必須是指定要發(fā)送到服務(wù)器的其他數(shù)據(jù)的對(duì)象,如果不需要此類數(shù)據(jù),則為None。目前,HTTP請(qǐng)求是唯一使用數(shù)據(jù)的請(qǐng)求。支持的對(duì)象類型包括字節(jié),類文件對(duì)象和可迭代。C.第三個(gè)參數(shù)header必須是一個(gè)字典類型,它是請(qǐng)求頭。D.第四個(gè)參數(shù)origin_req_host是請(qǐng)求方的host名稱或者IP地址。E.第五個(gè)參數(shù)unverifiable表示該請(qǐng)求是否無(wú)法核實(shí),默認(rèn)為false。無(wú)法驗(yàn)證的請(qǐng)求就是指用戶沒(méi)有權(quán)限去接受請(qǐng)求。F.第六個(gè)參數(shù)method是一個(gè)字符串,用來(lái)指示請(qǐng)求使用的方法,比如GET、POST和PUT等。發(fā)送請(qǐng)求——Request例(urllib02.py):fromurllibimportrequest,parseurl="/post"headers={"User-Agent":"Mozilla/4.0(compatible;MSIE5.5;WindowsNT)","Host":""}di={"name":"Germey"}data=bytes(parse.urlencode(di),encoding="utf-8")req=request.Request(url=url,data=data,headers=headers,method="POST")response=request.urlopen(req)print(response.read().decode("utf-8"))Request使用案例Request使用案例程序運(yùn)行結(jié)果urllib.error模塊為urllib.request引發(fā)的異常定義了異常類?;井惓n愂荱RLError。exceptionurllib.error.URLError:處理程序遇到問(wèn)題時(shí)會(huì)引發(fā)此異常(或派生異常)。它是OSError的子類。Request模塊產(chǎn)生的所有異常都可以由該類來(lái)進(jìn)行捕獲。Reason屬性可以查看異常的相關(guān)信息例:解析不存在的鏈接(urllib03.py)fromurllibimportrequest,errortry:response=request.urlopen("")excepterror.URLErrorasex:print(ex.reason)程序請(qǐng)求打開,但是實(shí)際上這個(gè)網(wǎng)址是不存在的,所以將會(huì)拋出URLError異常,reason屬性將會(huì)顯示異常類型為NotFound,所以程序運(yùn)行結(jié)果將是“NotFound”。處理異?!猠xceptionurllib.error.URLErrorHTTPError是URLError的一個(gè)子類,可以作為一個(gè)非特殊的文件類返回值(與urlopen()返回的相同)。在處理異常HTTP錯(cuò)誤(例如身份驗(yàn)證請(qǐng)求)時(shí)非常有用。該類有三個(gè)屬性:A、code:返回HTTP的狀態(tài)碼,例如400表示頁(yè)面不存在,500表示服務(wù)器錯(cuò)誤。B、reason:返回錯(cuò)誤原因。C、headers:返回請(qǐng)求頭信息。例:解析錯(cuò)誤連接(urllib04.py)fromurllibimportrequest,errortry:responserequest.urlopen("/pandas-docs/stabl")excepterror.HTTPErrorasex:print(ex.reason,ex.code,ex.headers,sep="\n")程序請(qǐng)求打開pandas官方文檔,但是誤將網(wǎng)址的最后一個(gè)單詞“stable”寫成了“stabl”,由于網(wǎng)址無(wú)法解析,所以程序捕獲到了異常,并打印出相關(guān)異常信息。處理異常——exceptionurllib.error.HTTPErrorurllib.parse模塊定義了一個(gè)標(biāo)準(zhǔn)接口,用于在組件中解析統(tǒng)一資源定位符(URL)字符串(尋址方案,網(wǎng)絡(luò)位置,路徑等),將組件組合回URL字符串,并將“相對(duì)URL”轉(zhuǎn)換為絕對(duì)URL給出“基本URL”。它支持以下URL方案:file,ftp,gopher,hdl,http,https,imap,mailto,mms,news,nntp,prospero,rsync,rtsp,rtspu,sftp,shttp,sIP,sIPs,snews,svn,svn+ssh,telnet,wais,ws,wss。urllib.parse模塊定義的功能分為兩大類:URL解析和URL引用。解析鏈接urlparse()函數(shù)側(cè)重于將URL字符串拆分url組件,或者將url組件組合為URL字符串。其函數(shù)原型如下:urllib.parse.urlparse(urlstring,scheme='',allow_fragments=True)urlparse()函數(shù)將一個(gè)url拆分為6個(gè)部分,其中包括scheme(協(xié)議名稱)、netloc(域名)、path(訪問(wèn)路徑)、params(訪問(wèn)參數(shù))、query(查詢條件)和fragment(錨點(diǎn))。函數(shù)包含三個(gè)參數(shù),第一個(gè)參數(shù)urlstring是必須的,代表的是需要解析的url地址;第二個(gè)參數(shù)scheme代指使用的協(xié)議,默認(rèn)為https;第三個(gè)參數(shù)allow_fragments表示是否忽略fragment,默認(rèn)為True。例:解析url(urllib05.py)fromurllib.parseimporturlparseo=urlparse('http://www.cwi.nl:80/%7Eguido/Python.html')print(o)print(o.scheme)print(o.port)print(o.geturl)urlparse()對(duì)于現(xiàn)有的一串GET請(qǐng)求參數(shù),該函數(shù)可以將其轉(zhuǎn)化為字典,其函數(shù)原型如下:urllib.parse.parse_qs(qs,keep_blank_values=False,strict_parsing=False,encoding='utf-8',errors='replace',max_num_fields=None)參數(shù)詳解A、參數(shù)qs是必填項(xiàng),指定需要轉(zhuǎn)化的請(qǐng)求參數(shù)。B、可選參數(shù)keep_blank_values是一個(gè)標(biāo)志,指示百分比編碼查詢中的空值是否應(yīng)被視為空字符串,默認(rèn)為False。C、可選參數(shù)strict_parsing是一個(gè)標(biāo)志,指示如何處理解析錯(cuò)誤。如果為false(默認(rèn)值),則會(huì)以忽略錯(cuò)誤D、可選的encoding和errors參數(shù)指定如何將百分比編碼的序列解碼為Unicode字符。E、可選參數(shù)max_num_fields是要讀取的最大字段數(shù)。例(urllib06.py):fromurllib.parseimportparse_qsquery="school=nwpu&&loc=shanxi"print(parse_qs(query))##{'school':['nwpu'],'loc':['shanxi']}parse_qs()該函數(shù)的原型為:urllib.parse.urlunparse(parts),該函數(shù)從urlparse()返回的元組中構(gòu)造URL例(urllib07.py):fromurllib.parseimporturlunparsedata=["http","","index.html","user","a=7","comment"]print(urlunparse(data))運(yùn)行結(jié)果:/index.html;user?a=7#commenturlunparse()urlsplit()函數(shù)的原型如下:urllib.parse.urlsplit(urlstring,scheme='',allow_fragments=True)該函數(shù)和urlparse()類似,但不會(huì)從URL中拆分params。因此只會(huì)返回5個(gè)結(jié)果。例(urllib08.py):fromurllib.parseimporturlsplitresult=urlsplit("/index.html")print(result)運(yùn)行結(jié)果:SplitResult(scheme='http',netloc='',path='/index.html',query='',fragment=‘’)可以發(fā)現(xiàn),在返回的元組中沒(méi)有params參數(shù),僅僅返回了5個(gè)結(jié)果。urlsplit()該函數(shù)的原型為:urllib.parse.urlunsplit(parts)該函數(shù)將urlsplit()返回的元組元素組合成一個(gè)完整的URL。該函數(shù)與urlunparse很相似,唯一的區(qū)別在于傳入的可迭代對(duì)象長(zhǎng)度必須是5。例(urllib09.py):fromurllib.parseimporturlunsplitdata=["http","","index.html","a=7","comment"]print(urlunsplit(data))運(yùn)行結(jié)果:/index.html?a=7#commenturlunsplit()在使用requests庫(kù)之前,我們需要安裝requests庫(kù),安裝方法可以通過(guò)pip或者conda命令進(jìn)行安裝,安裝成功之后,即可使用requests庫(kù):pipinstallrequests或condainstallrequests2、使用requests庫(kù)圖9安裝requests使用requests發(fā)送網(wǎng)絡(luò)請(qǐng)求非常簡(jiǎn)單,一開始需要導(dǎo)入requests模塊,然后獲取某個(gè)網(wǎng)頁(yè)。我們以獲取百度首頁(yè)信息為例:例(requests01.py):importrequestsr=requests.get("")有了一個(gè)名為r的Response對(duì)象,就可以從這個(gè)對(duì)象中獲取我們想要的信息。例(requests01.py):print(type(r))print(r.status_code)print(r.cookies)運(yùn)行結(jié)果:<class'requests.models.Response’>200<RequestsCookieJar[<CookieBDORZ=27315for./>]>發(fā)送請(qǐng)求需要為URL的查詢字符串傳遞某種數(shù)據(jù),通常我們可以手工來(lái)構(gòu)建URL,那么數(shù)據(jù)就會(huì)以鍵值對(duì)的形式置于URL中,跟在一個(gè)問(wèn)號(hào)后面,例如,/get?key=val。在requests庫(kù)中,可以通過(guò)params關(guān)鍵字來(lái)傳遞參數(shù),該參數(shù)通常以一個(gè)字符串字典的形式傳入。例(requests02.py):importrequestsparams={'key1':'value1','key2':'value2'}r=requests.get("/get",params=params)print(r.url)#打印出/get?key1=value1&key2=value2傳遞URL參數(shù)客戶端向服務(wù)器端發(fā)送請(qǐng)求之后,服務(wù)器端會(huì)給客戶端一個(gè)響應(yīng),我們可以通過(guò)requests庫(kù)來(lái)讀取服務(wù)器響應(yīng)的內(nèi)容。例(requests03.py):importrequestsr=requests.get('’)r.text該程序運(yùn)行之后,將返回百度首頁(yè)的html內(nèi)容。Requests能夠自動(dòng)解碼來(lái)自服務(wù)器的內(nèi)容,大多數(shù)unicode字符集都能夠被解碼。當(dāng)請(qǐng)求發(fā)出后,requests會(huì)基于HTTP頭部對(duì)響應(yīng)的編碼作出有根據(jù)的推測(cè),當(dāng)訪問(wèn)r.text時(shí),requests會(huì)根據(jù)其推測(cè)的進(jìn)行文本編碼。響應(yīng)內(nèi)容客戶端向服務(wù)器端發(fā)送請(qǐng)求之后,服務(wù)器端會(huì)給客戶端一個(gè)響應(yīng),我們可以通過(guò)requests庫(kù)來(lái)讀取服務(wù)器響應(yīng)的內(nèi)容。例:給相應(yīng)的請(qǐng)求添加content-type(requests04.py)importrequestsurl='/some/endpoint'headers={'user-agent':'my-app/0.0.1'}r=requests.get(url,headers=headers)Requests不會(huì)基于定制header的具體情況而改變自己的行為,只不過(guò)在最后的請(qǐng)求中,所有的header信息都會(huì)被傳遞進(jìn)去,在request中,所有的header的值必須是string、bytestring或者unicode。如果想要查看某個(gè)請(qǐng)求的請(qǐng)求頭,可以通過(guò)headers屬性來(lái)查看。定制請(qǐng)求頭Selenium是一個(gè)自動(dòng)化測(cè)試工具,利用它可以驅(qū)動(dòng)瀏覽器執(zhí)行特定的動(dòng)作,比如點(diǎn)擊、下拉等操作,同時(shí)還可以獲取瀏覽器當(dāng)前呈現(xiàn)的頁(yè)面的源代碼,做到可見即可爬。用戶可以通過(guò)命令pipinstallselenium進(jìn)行安裝。安裝完selenium之后,我們還需要下載ChromeDriver,我們使用的版本是2.30,可以進(jìn)入/mirrors/chromedriver/網(wǎng)站下載。3、使用Selenium獲取網(wǎng)頁(yè)圖10ChromeDriver版本在利用selenium獲取源代碼之前,我們需要將下載的ChromeDriver與代碼放在同一個(gè)文件夾下,以便調(diào)用。如果將其放在別的路徑下,就需要使用絕對(duì)路徑進(jìn)行調(diào)用。例(selenium01.py):#獲取百度源碼#初始化selenium并導(dǎo)入selenium庫(kù)fromseleniumimportwebdriver#使用相對(duì)路徑指定WebDriverdriver=webdriver.Chrome('chromedriver.exe')try:#使用selenium打開網(wǎng)頁(yè)

driver.get('')#獲取網(wǎng)頁(yè)源代碼

html=driver.page_source

print(html)#打印網(wǎng)頁(yè)源代碼finally:driver.close()獲取源代碼Selenium支持非常多的瀏覽器,如Chrome、Firefox、Edge、Safari等,也支持無(wú)界面瀏覽器PhantomJS,我們?cè)诔跏蓟瘯r(shí)可以進(jìn)行指定。例:driver=webdriver.Chrome()driver=webdriver.Firefox()driver=webdriver.Edge()driver=webdriver.PhantomJS()driver=webdriver.Safari()聲明瀏覽器類型如果想獲取網(wǎng)頁(yè)中的單個(gè)節(jié)點(diǎn)元素,Selenium也提供了很多方法。其中最常用的兩個(gè)為:□find_element_by_id():通過(guò)id獲取,返回符合條件的第一個(gè)□find_element_by_name():通過(guò)name獲取,返回符合條件的第一個(gè)例:獲取百度首頁(yè)搜索框節(jié)點(diǎn)獲取單個(gè)元素圖10百度首頁(yè)部分源碼可以看出,該搜索框的id為kw,name為wd。代碼例:獲取百度首頁(yè)搜索框節(jié)點(diǎn)(selenium02.py)fromseleniumimportwebdriver#使用相對(duì)路徑指定WebDriverdriver=webdriver.Chrome('chromedriver.exe')driver.get('')element_by_name=driver.find_element_by_name('wd')element_by_id=driver.find_element_by_id('kw')print(element_by_name)print(element_by_id)driver.close()程序運(yùn)行結(jié)果:<selenium.webdriver.remote.webelement.WebElement(session="8b071cb473e7717c25e90e0837df1adc",element="324c4d3f-5a07-4a30-86a4-f0999bab27c6")><selenium.webdriver.remote.webelement.WebElement(session="8b071cb473e7717c25e90e0837df1adc",element="324c4d3f-5a07-4a30-86a4-f0999bab27c6")>find_element_by_link_text:通過(guò)標(biāo)簽中的元素文本鏈接查找單個(gè)元素find_element_tag_name:通過(guò)標(biāo)簽名獲取單個(gè)元素find_element_by_class_name:通過(guò)class屬性名獲取單個(gè)元素find_element_by_css_selector:通過(guò)css選擇器獲取單個(gè)元素find_element_by_xpath:通過(guò)xpath的方式獲取單個(gè)元素Selenium還提供了一個(gè)find_element()方法,該方法也是獲取單個(gè)元素節(jié)點(diǎn),該方法需要傳入兩個(gè)參數(shù),第一個(gè)參數(shù)是查找方式,第二個(gè)參數(shù)是查找的值。比如通過(guò)id

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 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)論