《數(shù)據(jù)采集與處理:基于python》 課件 付東普 第8-10章 網(wǎng)絡(luò)數(shù)據(jù)采集、關(guān)系數(shù)據(jù)庫連接與訪問、大數(shù)據(jù)存儲與訪問技術(shù)_第1頁
《數(shù)據(jù)采集與處理:基于python》 課件 付東普 第8-10章 網(wǎng)絡(luò)數(shù)據(jù)采集、關(guān)系數(shù)據(jù)庫連接與訪問、大數(shù)據(jù)存儲與訪問技術(shù)_第2頁
《數(shù)據(jù)采集與處理:基于python》 課件 付東普 第8-10章 網(wǎng)絡(luò)數(shù)據(jù)采集、關(guān)系數(shù)據(jù)庫連接與訪問、大數(shù)據(jù)存儲與訪問技術(shù)_第3頁
《數(shù)據(jù)采集與處理:基于python》 課件 付東普 第8-10章 網(wǎng)絡(luò)數(shù)據(jù)采集、關(guān)系數(shù)據(jù)庫連接與訪問、大數(shù)據(jù)存儲與訪問技術(shù)_第4頁
《數(shù)據(jù)采集與處理:基于python》 課件 付東普 第8-10章 網(wǎng)絡(luò)數(shù)據(jù)采集、關(guān)系數(shù)據(jù)庫連接與訪問、大數(shù)據(jù)存儲與訪問技術(shù)_第5頁
已閱讀5頁,還剩153頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡介

第八章

網(wǎng)絡(luò)數(shù)據(jù)采集《數(shù)據(jù)采集與處理:基于Python》2024/5/1112024/5/112教學(xué)目標(biāo)本章學(xué)習(xí)目標(biāo)1.了解爬蟲的相關(guān)概念與知識,理解網(wǎng)絡(luò)數(shù)據(jù)的交互過程和原理及HTML和JavaScript的基本語法和結(jié)構(gòu);2.掌握靜態(tài)網(wǎng)頁內(nèi)容爬取常用Python模塊的基本方法和操作,理解不同模塊的功能特點(diǎn)和應(yīng)用區(qū)別;3.了解動(dòng)態(tài)網(wǎng)頁技術(shù),熟悉Selenium模塊爬取動(dòng)態(tài)網(wǎng)頁的方法;4.了解爬蟲框架Scrapy的基本結(jié)構(gòu)和基本原理,理解Scrapy的開發(fā)方法和步驟。本章提綱1.爬蟲相關(guān)概念與知識2.HTML與JavaScript基礎(chǔ)3.靜態(tài)網(wǎng)頁內(nèi)容爬取與解析4.動(dòng)態(tài)網(wǎng)頁內(nèi)容爬取5.BeautifulSoup用法6.requests基本操作與爬蟲案例7.selenium爬蟲案例爬蟲的相關(guān)概念與知識2024/5/113爬蟲的基本概念網(wǎng)絡(luò)爬蟲(WebSpider),又被稱為網(wǎng)頁蜘蛛,網(wǎng)絡(luò)機(jī)器人,有時(shí)也稱為網(wǎng)頁追逐者,是一種按照一定的規(guī)則,自動(dòng)地抓取互聯(lián)網(wǎng)上網(wǎng)頁中相應(yīng)信息(文本、圖片等)的程序或者腳本,然后把抓取的信息存儲到自己的計(jì)算機(jī)上。從功能上來講,網(wǎng)絡(luò)爬蟲一般分為數(shù)據(jù)采集,處理,儲存三個(gè)部分。它的基本原理和工作流程如下:網(wǎng)絡(luò)爬蟲按照系統(tǒng)結(jié)構(gòu)和實(shí)現(xiàn)技術(shù),大致可以分為傳統(tǒng)爬蟲、通用網(wǎng)絡(luò)爬蟲、聚焦網(wǎng)絡(luò)爬蟲等爬蟲的基本概念在大數(shù)據(jù)架構(gòu)中,數(shù)據(jù)收集與數(shù)據(jù)存儲占據(jù)了極為重要的地位,可以說是大數(shù)據(jù)的核心基礎(chǔ),而爬蟲技術(shù)在這兩大核心技術(shù)層次中占有很大的比例。爬蟲相關(guān)知識任意打開一個(gè)網(wǎng)頁(/),鼠標(biāo)右鍵單擊,從彈出的快捷菜單中選擇“檢查”(inspection),即可查看到該網(wǎng)頁結(jié)構(gòu)的相應(yīng)代碼瀏覽網(wǎng)頁及獲取內(nèi)容流程無論我們通過瀏覽器打開網(wǎng)站、訪問網(wǎng)頁,還是通過腳本對URL網(wǎng)址進(jìn)行訪問,本質(zhì)上都是對HTTP服務(wù)器的請求,瀏覽器上所呈現(xiàn)的、控制臺所顯示的都是HTTP服務(wù)器對我們請求的響應(yīng)。1)網(wǎng)頁請求和響應(yīng)的過程(1)Request(請求)。每一個(gè)用戶打開的網(wǎng)頁都必須在最開始由用戶向服務(wù)器發(fā)送訪問的請求。(2)Response(響應(yīng))。服務(wù)器在接收到用戶的請求后,會驗(yàn)證請求的有效性,然后向用戶發(fā)送相應(yīng)的內(nèi)容??蛻舳私邮盏椒?wù)器的響應(yīng)內(nèi)容后,再將此內(nèi)容展示出來,以供用戶瀏覽。瀏覽網(wǎng)頁及獲取內(nèi)容流程補(bǔ)充:HTTPRequest方法(Method)每個(gè)HTTP請求和響應(yīng)都遵循相同的格式,一個(gè)HTTP包含Head和Body兩部分,其中Body是可選的。Request訪問網(wǎng)絡(luò)資源的操作類型包括增刪改查,其方法一般有g(shù)et、post、put、delete、head等,最常用的是get和post方法。get一般用于獲取/查詢資源信息,而post一般用于更新資源信息

get提交請求的數(shù)據(jù)會附在URL之后(就是把數(shù)據(jù)放置在HTTP協(xié)議頭中),以?分割URL和傳輸數(shù)據(jù),多個(gè)參數(shù)用&連接;例如:login.action?name=hyddd&password=idontknow&verify=%E4%BD%A0%E5%A5%BD。如果數(shù)據(jù)是英文字母/數(shù)字,原樣發(fā)送,如果是空格,轉(zhuǎn)換為+,如果是中文/其他字符,則直接把字符串用BASE64加密,得出如:%E4%BD%A0%E5%A5%BD,其中%XX中的XX為該符號以16進(jìn)制表示的ASCII。而post把提交的數(shù)據(jù)放置在HTTP包的包體中。因此,get提交的數(shù)據(jù)會在地址欄中顯示出來,而post提交,地址欄不會改變。由于特定瀏覽器和服務(wù)器對URL長度有限制,因此對于get提交時(shí),傳輸數(shù)據(jù)就會受到URL長度的限制,而post不是通過URL傳值,理論上數(shù)據(jù)不受限。但實(shí)際各個(gè)Web服務(wù)器會規(guī)定對post提交數(shù)據(jù)大小進(jìn)行限制。post的安全性要比get的安全性高瀏覽網(wǎng)頁及獲取內(nèi)容流程2)用戶使用爬蟲來獲取網(wǎng)頁數(shù)據(jù)的時(shí)候,一般要經(jīng)過以下幾步:發(fā)送請求。獲取響應(yīng)內(nèi)容。解析內(nèi)容。保存數(shù)據(jù)。

爬蟲的總體知識與思維導(dǎo)圖基礎(chǔ)爬蟲框架基礎(chǔ)爬蟲框架主要包括:爬蟲調(diào)度器、URL管理器、HTML下載器、HTML解析器和數(shù)據(jù)存儲器:爬蟲調(diào)度器:統(tǒng)籌協(xié)調(diào)其他模塊的工作URL管理器:負(fù)責(zé)管理URL鏈接,維護(hù)已經(jīng)爬取的URL集合和未爬取的URL,提供獲取新URL鏈接的接口。HTML下載器:從URL管理器獲取未爬取的URL鏈接并下載HTML網(wǎng)頁。HTML解析器:從HTML下載器中獲取已經(jīng)下載的HTML網(wǎng)頁,并從中解析出新的URL鏈接交給URL管理器,解析出有效數(shù)據(jù)給數(shù)據(jù)存儲器。數(shù)據(jù)存儲器:將HTML解析器解析出的數(shù)據(jù)通過文件或數(shù)據(jù)庫的形式進(jìn)行存儲HTML與JavaScript基礎(chǔ)2024/5/1112HTML與JavaScript基礎(chǔ)如果只是編寫爬蟲程序的話,畢竟不是開發(fā)網(wǎng)站,所以只要能夠看懂HTML代碼基本上就可以了,不要求能編寫。當(dāng)然,對于一些高級爬蟲和特殊的網(wǎng)站,還需要具有深厚的JavaScript功底,或者JQuery、AJAX等知識。13HTML基礎(chǔ)(1)h標(biāo)簽在HTML代碼中,使用h1到h6表示不同級別的標(biāo)題,其中h1級別的標(biāo)題字體最大,h6級別的標(biāo)題字體最小。該標(biāo)簽的用法為:<h1>一級標(biāo)題</h1><h2>二級標(biāo)題</h2><h3>三級標(biāo)題</h3>14HTML基礎(chǔ)(2)p標(biāo)簽在HTML代碼中,p標(biāo)簽表示段落,用法為:<p>這是一個(gè)段落</p>15HTML基礎(chǔ)(3)a標(biāo)簽在HTML代碼中,a標(biāo)簽表示超鏈接,使用時(shí)需要指定鏈接地址(由href屬性來指定)和在頁面上顯示的文本,用法為:<ahref="">點(diǎn)這里</a>16HTML基礎(chǔ)(4)img標(biāo)簽在HTML代碼中,img標(biāo)簽用來顯示一個(gè)圖像,并使用src屬性指定圖像文件地址,可以使用本地文件,也可以指定網(wǎng)絡(luò)上的圖片。例如:<imgsrc="Python可以這樣學(xué).jpg"width="200"height="300"/><imgsrc="/upload/bigbookimg/072406-01.jpg"width="200"height="300"/>17HTML基礎(chǔ)(5)table、tr、td標(biāo)簽在HTML代碼中,table標(biāo)簽用來創(chuàng)建表格,tr用來創(chuàng)建行,td用來創(chuàng)建單元格,用法為:<tableborder="1"><tr><td>第一行第一列</td><td>第一行第二列</td></tr><tr><td>第二行第一列</td><td>第二行第二列</td></tr></table>18HTML基礎(chǔ)(6)ul、ol、li在HTML代碼中,ul標(biāo)簽用來創(chuàng)建無序列表,ol標(biāo)簽用來創(chuàng)建有序列表,li標(biāo)簽用來創(chuàng)建其中的列表項(xiàng)。例如,下面是ul和li標(biāo)簽的用法:<ulid="colors"name="myColor"><li>紅色</li><li>綠色</li><li>藍(lán)色</li></ul>19HTML基礎(chǔ)(7)div標(biāo)簽在HTML代碼中,div標(biāo)簽用來創(chuàng)建一個(gè)塊(即division),其中可以包含其他標(biāo)簽,例如:<divid="yellowDiv"style="background-color:yellow;border:#FF00001pxsolid;"><ol><li>紅色</li><li>綠色</li><li>藍(lán)色</li></ol></div><divid="reddiv"style="background-color:red"><p>第一段</p><p>第二段</p></div>20JavaScript基礎(chǔ)(1)在網(wǎng)頁中使用JavaScript代碼的方式可以在HTML標(biāo)簽的事件屬性中直接添加JavaScript代碼。例如,把下面的代碼保存為index.html文件并使用瀏覽器打開,單擊按鈕“保存”,網(wǎng)頁會彈出提示“保存成功”。<html><body><form><inputtype="button"value="保存"onClick="alert('保存成功');"></form></body></html>21JavaScript基礎(chǔ)對于較多但僅在個(gè)別網(wǎng)頁中用到的JavaScript代碼,可以寫在網(wǎng)頁中的<script>標(biāo)簽中。例如,下面的代碼保存為index.html并使用瀏覽器打開,會發(fā)現(xiàn)頁面上顯示的是“動(dòng)態(tài)內(nèi)容”而不是“靜態(tài)內(nèi)容”。<html><body><divid="test">靜態(tài)內(nèi)容</div></body><scripttype="text/javascript">document.getElementById("test").innerHTML="動(dòng)態(tài)內(nèi)容";</script></html>22JavaScript基礎(chǔ)如果一個(gè)網(wǎng)站中會用到大量的JavaScript代碼,一般會把這些代碼按功能劃分到不同函數(shù)中,并把這些函數(shù)封裝到一個(gè)擴(kuò)展名為js的文件中,然后在網(wǎng)頁中使用。例如,和網(wǎng)頁在同一個(gè)文件夾中的myfunctions.js內(nèi)容如下:functionmodify(){document.getElementById("test").innerHTML="動(dòng)態(tài)內(nèi)容";}在下面的頁面文件中,把外部文件myfunctions.js導(dǎo)入,然后調(diào)用了其中的函數(shù):<html><head><scripttype="text/javascript"src="myfunctions.js"></script></head><body><divid="test">靜態(tài)內(nèi)容</div></body><scripttype="text/javascript">modify();</script></html>23JavaScript基礎(chǔ)(2)常用JavaScript事件把下面的代碼保存為index.html并使用瀏覽器打開,會發(fā)現(xiàn)在每次頁面加載時(shí)都會彈出提示,但在頁面上進(jìn)行其他操作時(shí),并不會彈出提示。<html><bodyonLoad="alert('頁面開始加載');"><divid="test">靜態(tài)內(nèi)容</div></body></html>24JavaScript基礎(chǔ)除了常用的事件之外,還有一些特殊的方式可以執(zhí)行JavaScript代碼。例如,下面的代碼演示了在鏈接標(biāo)簽<a>中使用href屬性指定JavaScript代碼的用法。<html><scripttype="text/javascript">functiontest(){alert('提示信息');}</script><body><ahref="javascript:test();">點(diǎn)這里</a></body></html>25JavaScript基礎(chǔ)(3)常用JavaScript對象下面的代碼演示了prompt()方法的用法,將其保存為文件index.html并使用瀏覽器打開,會提示用戶輸入任意內(nèi)容,然后在頁面上輸出相應(yīng)的信息。<html><scripttype="text/javascript">varcity=prompt("請輸入一個(gè)城市名稱:","煙臺");document.write("你輸入的是:"+city);</script><body></body></html>26JavaScript基礎(chǔ)把下面的代碼保存為文件index.html,此時(shí)頁面上會顯示圖像文件1.jpg的內(nèi)容,單擊該圖像時(shí)會切換成為2.jpg的內(nèi)容。<html><body><imgname="img1"src="1.jpg"onClick="document.img1.src='2.jpg';"/></body></html>27靜態(tài)網(wǎng)頁內(nèi)容爬取與解析2024/5/1128urllib基本應(yīng)用與爬蟲案例Python3.x標(biāo)準(zhǔn)庫urllib提供了urllib.request、urllib.response、urllib.parse和urllib.error四個(gè)模塊,很好地支持了網(wǎng)頁內(nèi)容讀取功能。再結(jié)合Python字符串方法和正則表達(dá)式,可以完成一些簡單的網(wǎng)頁內(nèi)容爬取工作,也是理解和使用其他爬蟲庫的基礎(chǔ)。URL的一般格式為(帶方括號[]的為可選項(xiàng)):protocol://hostname[port]/path/[;parameters][?query]#fragment。29urllib的基本應(yīng)用1.讀取并顯示網(wǎng)頁內(nèi)容>>>importurllib.request>>>fp=urllib.request.urlopen(r'')>>>print(fp.read(100))#讀取100個(gè)字節(jié)>>>print(fp.read(100).decode())#使用UTF8進(jìn)行解碼>>>fp.close()#關(guān)閉連接30urllib的基本應(yīng)用2.提交網(wǎng)頁參數(shù)(1)下面的代碼演示了如何使用GET方法讀取并顯示指定url的內(nèi)容。>>>importurllib.request>>>importurllib.parse>>>params=urllib.parse.urlencode({'spam':1,'eggs':2,'bacon':0})>>>url="/?%s"%params>>>withurllib.request.urlopen(url)asf:print(f.read().decode('utf-8'))31urllib的基本應(yīng)用(2)下面的代碼演示了如何使用POST方法提交參數(shù)并讀取指定頁面內(nèi)容。>>>importurllib.request>>>importurllib.parse>>>data=urllib.parse.urlencode({'spam':1,'eggs':2,'bacon':0})>>>data=data.encode('ascii')>>>withurllib.request.urlopen("http://",data)asf:print(f.read().decode('utf-8'))32urllib的基本應(yīng)用3.使用HTTP代理訪問頁面>>>importurllib.request>>>proxies={'http':':8080/'}>>>opener=urllib.request.FancyURLopener(proxies)>>>withopener.open("")asf:f.read().decode('utf-8')33BeautifulSoup用法簡介BeautifulSoup(簡稱bs)是一個(gè)可以從HTML或XML文件中提取數(shù)據(jù)的Python庫。它通過轉(zhuǎn)換器實(shí)現(xiàn)文檔導(dǎo)航、查找、修改文檔的方式。bs最大的特點(diǎn)是簡單易用,不像正則表達(dá)式和xPath需要刻意去記住很多特定語法,盡管那樣會效率更高更直接。安裝方式:隨anaconda附帶,也可以通過pip安裝:pipinstallbeautifulsoup4使用流程:通過文本初始化bs對象->通過find/find_all或其他方法檢測信息->輸出或保存bs在使用時(shí)需要指定一個(gè)“解析器”:1)html.parse-python自帶,但容錯(cuò)性不夠高,對于一些寫得不太規(guī)范的網(wǎng)頁會丟失部分內(nèi)容2)lxml-解析速度快,需額外安裝3)xml-同屬lxml庫,支持XML文檔4)html5lib-最好的容錯(cuò)性,但速度稍慢34BeautifulSoup用法簡介>>>frombs4importBeautifulSoup>>>BeautifulSoup('helloworld!','lxml')#自動(dòng)添加標(biāo)簽<html><body><p>helloworld!</p></body></html>>>>BeautifulSoup('<span>helloworld!','lxml')#自動(dòng)補(bǔ)全標(biāo)簽<html><body><span>helloworld!</span></body></html>>>>html_doc="""<html><head><title>TheDormouse'sstory</title></head><body><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>"""35BeautifulSoup用法簡介>>>soup=BeautifulSoup(html_doc,'html.parser')#也可以指定lxml或其他解析器

>>>print(soup.prettify())#以優(yōu)雅的方式顯示出來<html><head><title>TheDormouse'sstory</title></head><body><pclass="title"><b>TheDormouse'sstory</b></p><pclass="story">Onceuponatimetherewerethreelittlesisters;andtheirnameswere<aclass="sister"href="/elsie"id="link1">Elsie</a>,<aclass="sister"href="/lacie"id="link2">Lacie</a>and<aclass="sister"href="/tillie"id="link3">Tillie</a>;andtheylivedatthebottomofawell.</p><pclass="story">...</p></body></html>36BeautifulSoup用法簡介>>>soup.title#訪問<title>標(biāo)簽的內(nèi)容<title>TheDormouse'sstory</title>>>>#查看標(biāo)簽的名字'title'>>>soup.title.text#查看標(biāo)簽的文本"TheDormouse'sstory">>>soup.title.string#查看標(biāo)簽的文本"TheDormouse'sstory">>>soup.title.parent#查看上一級標(biāo)簽<head><title>TheDormouse'sstory</title></head>>>>soup.head<head><title>TheDormouse'sstory</title></head>>>>soup.b#訪問<b>標(biāo)簽的內(nèi)容<b>TheDormouse'sstory</b>>>>soup.body.b#訪問<body>中<b>標(biāo)簽的內(nèi)容<b>TheDormouse'sstory</b>>>>#把整個(gè)BeautifulSoup對象看作標(biāo)簽對象'[document]'37BeautifulSoup用法簡介>>>soup.body#查看body標(biāo)簽內(nèi)容<body><pclass="title"><b>TheDormouse'sstory</b></p><pclass="story">Onceuponatimetherewerethreelittlesisters;andtheirnameswere<aclass="sister"href="/elsie"id="link1">Elsie</a>,<aclass="sister"href="/lacie"id="link2">Lacie</a>and<aclass="sister"href="/tillie"id="link3">Tillie</a>;andtheylivedatthebottomofawell.</p><pclass="story">...</p></body>38BeautifulSoup用法簡介>>>soup.p#查看段落信息<pclass="title"><b>TheDormouse'sstory</b></p>>>>soup.p['class']#查看標(biāo)簽屬性['title']>>>soup.p.get('class')#也可以這樣查看標(biāo)簽屬性['title']>>>soup.p.text#查看段落文本"TheDormouse'sstory">>>soup.p.contents#查看段落內(nèi)容[<b>TheDormouse'sstory</b>]>>>soup.a<aclass="sister"href="/elsie"id="link1">Elsie</a>>>>soup.a.attrs#查看標(biāo)簽所有屬性{'class':['sister'],'href':'/elsie','id':'link1'}39BeautifulSoup用法簡介>>>soup.find_all('a')#查找所有<a>標(biāo)簽[<aclass="sister"href="/elsie"id="link1">Elsie</a>,<aclass="sister"href="/lacie"id="link2">Lacie</a>,<aclass="sister"href="/tillie"id="link3">Tillie</a>]>>>soup.find_all(['a','b'])#同時(shí)查找<a>和<b>標(biāo)簽[<b>TheDormouse'sstory</b>,<aclass="sister"href="/elsie"id="link1">Elsie</a>,<aclass="sister"href="/lacie"id="link2">Lacie</a>,<aclass="sister"href="/tillie"id="link3">Tillie</a>]40BeautifulSoup用法簡介>>>importre>>>soup.find_all(href=pile("elsie"))#查找href包含特定關(guān)鍵字的標(biāo)簽[<aclass="sister"href="/elsie"id="link1">Elsie</a>]>>>soup.find(id='link3')#查找屬性id='link3'的標(biāo)簽<aclass="sister"href="/tillie"id="link3">Tillie</a>>>>soup.find_all('a',id='link3')#查找屬性'link3'的a標(biāo)簽[<aclass="sister"href="/tillie"id="link3">Tillie</a>]>>>forlinkinsoup.find_all('a'):print(link.text,':',link.get('href'))

Elsie:/elsieLacie:/lacieTillie:/tillie41BeautifulSoup用法簡介>>>print(soup.get_text())#返回所有文本TheDormouse'sstoryTheDormouse'sstoryOnceuponatimetherewerethreelittlesisters;andtheirnameswereElsie,LacieandTillie;andtheylivedatthebottomofawell....>>>soup.a['id']='test_link1'#修改標(biāo)簽屬性的值>>>soup.a<aclass="sister"href="/elsie"id="test_link1">Elsie</a>>>>soup.a.string.replace_with('test_Elsie')#修改標(biāo)簽文本'Elsie'>>>soup.a.string'test_Elsie'42BeautifulSoup用法簡介>>>forchildinsoup.body.children:#遍歷直接子標(biāo)簽print(child)<pclass="title"><b>TheDormouse'sstory</b></p><pclass="story">Onceuponatimetherewerethreelittlesisters;andtheirnameswere<aclass="sister"href="/elsie"id="test_link1">test_Elsie</a>,<aclass="sister"href="/lacie"id="link2">Lacie</a>and<aclass="sister"href="/tillie"id="link3">Tillie</a>;andtheylivedatthebottomofawell.</p><pclass="story">...</p>43BeautifulSoup用法簡介>>>test_doc='<html><head></head><body><p></p><p></p></body></html>'>>>s=BeautifulSoup(test_doc,'lxml')>>>forchildins.html.children:#遍歷直接子標(biāo)簽print(child)

<head></head><body><p></p><p></p></body>>>>forchildins.html.descendants:#遍歷子孫標(biāo)簽print(child)

<head></head><body><p></p><p></p></body><p></p><p></p>44requests基本操作與爬蟲案例Python擴(kuò)展庫requests可以使用比標(biāo)準(zhǔn)庫urllib更簡潔的形式來處理HTTP協(xié)議和解析網(wǎng)頁內(nèi)容,也是比較常用的爬蟲工具之一,完美支持Python3.x,使用pip可以直接在線安裝。Requests是用Python語言編寫,基于urllib,采用Apache2Licensed開源協(xié)議的HTTP庫。它比urllib更加方便,可以節(jié)約開發(fā)者大量的工作,完全滿足HTTP測試需求。安裝成功之后,使用下面的方式導(dǎo)入這個(gè)庫:>>>importrequests45requests基本操作(1)增加頭部并設(shè)置訪問代理>>>url='/some/endpoint'>>>headers={'user-agent':'my-app/0.0.1'}>>>r=requests.get(url,headers=headers)46requests基本操作(2)訪問網(wǎng)頁并提交數(shù)據(jù)>>>payload={'key1':'value1','key2':'value2'}>>>r=requests.post("/post",data=payload)>>>print(r.text)#查看網(wǎng)頁信息,略去輸出結(jié)果>>>url='/some/endpoint'>>>payload={'some':'data'}>>>r=requests.post(url,json=payload)>>>print(r.text)#查看網(wǎng)頁信息,略去輸出結(jié)果>>>print(r.headers)#查看頭部信息,略去輸出結(jié)果>>>print(r.headers['Content-Type'])application/json;charset=utf-8>>>print(r.headers['Content-Encoding'])gzip47requests基本操作(3)獲取和設(shè)置cookies下面的代碼演示了使用get()方法獲取網(wǎng)頁信息時(shí)cookies屬性的用法:>>>r=requests.get("/")>>>r.cookies#查看cookies<RequestsCookieJar[Cookie(version=0,name='BDORZ',value='27315',port=None,port_specified=False,domain='.',domain_specified=True,domain_initial_dot=True,path='/',path_specified=True,secure=False,expires=1521533127,discard=False,comment=None,comment_url=None,rest={},rfc2109=False)]>48requests基本操作下面的代碼演示了使用get()方法獲取網(wǎng)頁信息時(shí)設(shè)置cookies參數(shù)的用法:>>>url='/cookies'>>>cookies=dict(cookies_are='working')>>>r=requests.get(url,cookies=cookies)#設(shè)置cookies>>>print(r.text){"cookies":{"cookies_are":"working"}}49requests爬蟲案例例:讀取并下載指定的URL的圖片文件。>>>importrequests>>>picUrl=r'/static/opengraph-icon-200x200.png'>>>r=requests.get(picUrl)>>>r.status_code200>>>withopen('pic.png','wb')asfp:fp.write(r.content)#把圖像數(shù)據(jù)寫入本地文件50網(wǎng)頁JSON數(shù)據(jù)爬取與解析網(wǎng)頁JSON數(shù)據(jù)的爬取與解析使用API的主要形式——具象狀態(tài)傳輸(representationalstatetransfer,REST),它在Web上公開。RESTAPI使用統(tǒng)一資源標(biāo)識符(uniformresourceidentifier,URI;URL是URI的特定形式)來指定要處理的API。RESTAPI可以以不同形式返回?cái)?shù)據(jù),最常見的是JSON和XML,在這兩者中,JSON占主導(dǎo)地位。JSON代表JavaScript對象表示法,是一種非常方便的格式。下面使用requests庫來獲取國際空間站ISS的當(dāng)前位置。51importrequests#通過OpenNotifyAPI請求獲取國際空間站ISS的最新位置response=requests.get("/iss-now.json")response#返回結(jié)果:<Response[200]>網(wǎng)頁JSON數(shù)據(jù)爬取與解析我們收到了回復(fù),狀態(tài)是200。200是一個(gè)狀態(tài)碼(你可能在網(wǎng)頁上看到過“404錯(cuò)誤”)。以下是一些常見的訪問網(wǎng)站的響應(yīng)代碼:●200:一切正常,結(jié)果已經(jīng)返回(如果有的話)?!?01:服務(wù)器將你重定向到另一個(gè)端點(diǎn)。當(dāng)公司切換域名或端點(diǎn)名稱更改時(shí),可能會發(fā)生這種情況。●401:服務(wù)器認(rèn)為你沒有經(jīng)過身份驗(yàn)證。當(dāng)你沒有發(fā)送正確的憑證來訪問API時(shí),就會發(fā)生這種情況?!?00:服務(wù)器認(rèn)為你做了一個(gè)錯(cuò)誤的請求。這種情況可能發(fā)生在你沒有發(fā)送正確的數(shù)據(jù)時(shí)?!?03:你試圖訪問的資源是被禁止的,你沒有權(quán)限查看?!?04:你試圖訪問的資源在服務(wù)器上沒有找到。讀取JSON內(nèi)容的示例程序如下:52網(wǎng)頁JSON數(shù)據(jù)爬取與解析JSON讀取的內(nèi)容看起來像一個(gè)字典,有key-value對,可以使用json庫將JSON轉(zhuǎn)換為對象。示例程序如下:運(yùn)行結(jié)果如下:53importjsonresponse_d=json.loads(response_j)print(type(response_d))print(response_d)response_d["iss_position"]#或者使用pandas模塊直接讀入,pandas也可以讀入JSONimportpandasaspddf=pd.read_json(response_j)dfpandas讀取table標(biāo)簽內(nèi)容HTML的table標(biāo)簽組織的表格數(shù)據(jù)還可以使用pandas的read_html函數(shù)直接讀取,裝載為DataFrame對象。下面的示例程序展示了如何讀取新浪股票網(wǎng)頁中的表格數(shù)據(jù)。54importpandasaspd#由于網(wǎng)站更新,鏈接可能無效pd.set_option(display.width,None)url=/stock/df=pd.read_html(url)[6]#返回值為DataFrame數(shù)組,取第7個(gè)df.head()正則表達(dá)式與網(wǎng)頁內(nèi)容解析正則表達(dá)式是字符串處理的有力工具,它使用預(yù)定義的模式去匹配一類具有共同特征的字符串,可以快速、準(zhǔn)確地完成復(fù)雜的查找、替換等處理要求。與字符串自身提供的方法相比,正則表達(dá)式提供了更強(qiáng)大的處理功能。例如,使用字符串對象的split方法只能指定一個(gè)分隔符,而使用正則表達(dá)式可以很方便地指定多個(gè)符號作為分隔符;使用字符串對象的split方法指定分隔符時(shí),很難處理分隔符連續(xù)多次出現(xiàn)的情況,而正則表達(dá)式讓這一切都變得非常簡單。此外,正則表達(dá)式在文本編輯與處理、網(wǎng)頁爬蟲等場合中也有重要應(yīng)用。1.正則表達(dá)式的語法(1)正則表達(dá)式的基本語法。正則表達(dá)式由元字符及其不同組合構(gòu)成,巧妙構(gòu)造的正則表達(dá)式可以匹配任意字符串,完成查找、替換、分隔等復(fù)雜的字符串處理任務(wù)。正則表達(dá)式的元字符及其功能說明如表8-1所示。55正則表達(dá)式與網(wǎng)頁內(nèi)容解析56元字符功能說明.匹配除換行符以外的任意單個(gè)字符*匹配位于“*”之前的字符或子模式的0次或多次出現(xiàn)+匹配位于“+”之前的字符或子模式的1次或多次出現(xiàn)-在[]之內(nèi)用來表示范圍|匹配位于“|”之前或之后的字符^匹配行首,匹配以“^”后面的字符開頭的字符串$匹配行尾,匹配以“$”之前的字符結(jié)束的字符串?匹配位于“?”之前的0個(gè)或1個(gè)字符。當(dāng)此字符緊隨任何其他限定符(*、+、?、{n}、{n,}、{n,m})之后時(shí),匹配模式是“非貪心的”?!胺秦澬牡摹蹦J狡ヅ渌阉鞯降谋M可能短的字符串,而默認(rèn)的“貪心的”模式匹配搜索到的盡可能長的字符串。例如,在字符串“oooo”中,“o+?”只匹配單個(gè)“o”,而“o+”匹配所有“o”\表示位于“\”之后的為轉(zhuǎn)義字符\num此處的num是一個(gè)正整數(shù),表示子模式編號。例如,“(.)\1”匹配兩個(gè)連續(xù)的相同字符\f匹配換頁符\n匹配換行符\r匹配一個(gè)回車符\b匹配單詞頭或單詞尾\B與“\b”含義相反\d匹配任何數(shù)字,相當(dāng)于[0-9]\D與“\d”含義相反,等效于[^0-9]\s匹配任意空白字符,包括空格、制表符、換頁符,與[\f\n\r\t\v]等效\S與“\s”含義相反\w匹配任意字母、數(shù)字以及下劃線,相當(dāng)于[a-zA-Z0-9_]\W與“\w”含義相反,與“[^A-Za-z0-9_]”等效()將位于()內(nèi)的內(nèi)容作為一個(gè)整體來對待{m,n}{}前的字符或子模式重復(fù)至少m次、至多n次[]表示范圍,匹配位于[]中的任意一個(gè)字符[^xyz]反向字符集,匹配除x、y、z之外的任意字符[a-z]字符范圍,匹配指定范圍內(nèi)的任意字符[^a-z]反向范圍字符,匹配除小寫英文字母之外的任意字符正則表達(dá)式與網(wǎng)頁內(nèi)容解析正則表達(dá)式的基本語法如下:●如果以“\”開頭的元字符與轉(zhuǎn)義字符相同,則需要使用“\\”,或者使用原始字符串?!裨谧址凹由献址皉”或“R”之后表示原始字符串,此時(shí)字符串中任意字符都不再進(jìn)行轉(zhuǎn)義。原始字符串可以減少用戶的輸入,主要用于正則表達(dá)式和文件路徑字符串的情況,但如果字符串以一個(gè)斜線“\”結(jié)束,則需要多寫一個(gè)斜線,即以“\\”結(jié)束。(2)正則表達(dá)式的擴(kuò)展語法。正則表達(dá)式還有一些擴(kuò)展語法,如:●正則表達(dá)式使用圓括號“()”表示一個(gè)子模式,圓括號內(nèi)的內(nèi)容作為一個(gè)整體對待,例如,(red)+可以匹配redred和redredred等一個(gè)或多個(gè)重復(fù)red的情況?!袷褂米幽J綌U(kuò)展語法可以實(shí)現(xiàn)更加復(fù)雜的字符串處理功能。正則表達(dá)式的擴(kuò)展語法及其功能說明如表8-2所示。57正則表達(dá)式與網(wǎng)頁內(nèi)容解析58語法功能說明(?P<groupname>)為子模式命名(?iLmsux)設(shè)置匹配標(biāo)志,可以是幾個(gè)字母的組合,每個(gè)字母的含義與編譯標(biāo)志相同(?:...)匹配但不捕獲該匹配的子表達(dá)式(?P=groupname)表示在此之前命名為groupname的子模式(?#…)表示注釋(?<=…)用在正則表達(dá)式之前,表示如果“<=”后的內(nèi)容在字符串中不出現(xiàn),則匹配,但不返回“<=”之后的內(nèi)容(?=…)用在正則表達(dá)式之后,表示如果“=”后的內(nèi)容在字符串中出現(xiàn),則匹配,但不返回“=”之后的內(nèi)容(?<!…)用在正則表達(dá)式之前,表示如果“<!”后的內(nèi)容在字符串中不出現(xiàn),則匹配,但不返回“<!”之后的內(nèi)容(?!…)用在正則表達(dá)式之后,表示如果“!”后的內(nèi)容在字符串中不出現(xiàn),則匹配,但不返回“!”之后的內(nèi)容正則表達(dá)式與網(wǎng)頁內(nèi)容解析(3)正則表達(dá)式集錦。●最簡單的正則表達(dá)式是普通字符串,可以匹配自身?!馵pjc]ython可以匹配Pythonjythoncython。●[a-zA-Z0-9]可以匹配任意大小寫字母或數(shù)字。●[^abc]可以匹配除abc之外的任意字符。●Python|perl或p(ython|erl)都可以匹配Python或perl?!褡幽J胶竺婕由蠁柼柋硎究蛇x。r(http://)?(www\.)?Python\.org只能匹配http://www.Phttp://Pwww.PP。●^http只能匹配所有以http開頭的字符串?!?pattern)*:允許模式重復(fù)0次或多次?!?pattern)+:允許模式重復(fù)1次或多次?!?pattern){m,n}:允許模式重復(fù)m~n次。使用時(shí)需要注意,正則表達(dá)式只是進(jìn)行形式上的檢查,并不保證內(nèi)容一定正確。例如,正則表達(dá)式^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$可以檢查字符串是否為IP地址,字符串888.888.888.888也能通過檢查,但實(shí)際上并不是有效的IP地址。同理,正則表達(dá)式^\d{18}|\d{15}$只負(fù)責(zé)檢查字符串是否為18位或15位數(shù)字,并不保證一定是合法的身份證號。59正則表達(dá)式與網(wǎng)頁內(nèi)容解析2.正則表達(dá)式模塊rePython標(biāo)準(zhǔn)庫re模塊提供了正則表達(dá)式操作所需的功能,下表是有關(guān)方法及其功能說明。60方法功能說明findall(pattern,string[,flags])返回包含字符串中所有與給定模式匹配的項(xiàng)的列表match(pattern,string[,flags])從字符串的開始處匹配模式,返回match對象或Nonesearch(pattern,string[,flags])在整個(gè)字符串中搜索模式,返回match對象或Nonesplit(pattern,string[,maxsplit=0])根據(jù)模式匹配項(xiàng)分隔字符串sub(pat,repl,string[,count=0])將字符串中所有與pat匹配的項(xiàng)用repl替換,返回新字符串,repl可以是字符串或返回字符串的可調(diào)用對象,作用于每個(gè)匹配的match對象compile(pattern,flags=0)使用任何可選的標(biāo)記來編譯正則表達(dá)式的模式,然后返回一個(gè)正則表達(dá)式對象。推薦預(yù)編譯,但不是必需的正則表達(dá)式與網(wǎng)頁內(nèi)容解析其中函數(shù)的參數(shù)“flags”的值可以是下面幾種類型的不同組合(使用“|”進(jìn)行組合):●re.I:注意是大寫字母I,不是數(shù)字1,表示忽略大小寫?!駌e.L:支持本地字符集的字符?!駌e.M:多行匹配模式?!駌e.S:使元字符“.”匹配任意字符,包括換行符?!駌e.U:匹配Unicode字符?!駌e.X:忽略模式中的空格,并可以使用“#”注釋。正則表達(dá)式解析的示例程序如下:61>>>importre>>>example=Beautifulisbetterthanugly.>>>re.findall(\\b\w.+?\\b,example)#所有單詞[Beautiful,is,better,than,ugly]>>>re.findall(\w+,example) #所有單詞[Beautiful,is,better,than,ugly]>>>re.findall(r\b\w.+?\b,example) #使用原始字符串[Beautiful,is,better,than,ugly]>>>re.split(\s,example)#使用任何空白字符分隔字符串[Beautiful,is,better,than,ugly.]>>>re.findall(\d+\.\d+\.\d+,Python2.7.13) #查找x.x.x形式的數(shù)字[2.7.13]>>>re.findall(\d+\.\d+\.\d+,Python2.7.13,Python3.6.0)[2.7.13,3.6.0]>>>s=<html><head>Thisishead.</head><body>Thisisbody.</body></html>>>>pattern=r<html><head>(.+)</head><body>(.+)</body></html>>>>result=re.search(pattern,s)>>>result.group(1)#第一個(gè)子模式Thisishead.>>>result.group(2) #第二個(gè)子模式Thisisbody.正則表達(dá)式與網(wǎng)頁內(nèi)容解析3.match對象正則表達(dá)式對象的match方法和search方法在匹配成功后返回match對象。match對象的主要方法有:●group:返回匹配的一個(gè)或多個(gè)子模式的內(nèi)容?!駁roups:返回一個(gè)包含匹配的所有子模式內(nèi)容的元組。●groupdict:返回包含匹配的所有命名子模式內(nèi)容的字典?!駍tart:返回指定子模式內(nèi)容的起始位置?!馿nd:返回指定子模式內(nèi)容的結(jié)束位置的前一個(gè)位置?!駍pan:返回一個(gè)包含指定子模式內(nèi)容的起始位置和結(jié)束位置的前一個(gè)位置的元組。match對象應(yīng)用的示例程序如下:62>>>m=re.match(r"(?P<first_name>\w+)(?P<last_name>\w+)","MalcolmReynolds")>>>m.group(first_name)#使用命名的子模式Malcolm>>>m.group(last_name)Reynolds>>>m=re.match(r"(\d+)\.(\d+)","24.1632")>>>m.groups()#返回所有匹配的子模式(不包括第0個(gè))(24,1632)>>>m=re.match(r"(?P<first_name>\w+)(?P<last_name>\w+)","MalcolmReynolds")>>>m.groupdict()#以字典形式返回匹配的結(jié)果{first_name:Malcolm,last_name:Reynolds}網(wǎng)站爬蟲聲明雖然網(wǎng)站網(wǎng)頁的內(nèi)容是公開的,但爬取數(shù)據(jù)畢竟是不請自來的,而且當(dāng)收集大量數(shù)據(jù)時(shí),會給服務(wù)器帶來相當(dāng)高的負(fù)載。因此,網(wǎng)站管理員通常會在網(wǎng)站上公布其所允許的爬取類型。過度爬取之前應(yīng)該看一下網(wǎng)站根目錄下robots.txt文件的服務(wù)條款和有關(guān)域的聲明,了解哪些內(nèi)容允許爬取,哪些內(nèi)容不允許爬取。robots.txt文件一般在網(wǎng)站的根目錄下,例如,可以看一下百度學(xué)術(shù)的robots.txt文件的內(nèi)容(網(wǎng)址:/robots.txt)。示例內(nèi)容如下:

這里,它指定了不允許爬取的許多頁面,有的禁止動(dòng)態(tài)地生成查詢。常見的網(wǎng)站會要求用戶延遲爬取:63User-agent:BaiduspiderDisallow:/baiduDisallow:/s?...Crawl-delay:30Request-rate:1/30網(wǎng)站爬蟲聲明用戶應(yīng)該尊重這些限制?,F(xiàn)在,沒有人可以阻止你通過爬蟲程序運(yùn)行一個(gè)請求,但如果你在短時(shí)間內(nèi)請求了很多頁面,像谷歌、百度這樣的網(wǎng)站就會迅速阻止你。動(dòng)態(tài)爬取的另一種策略是下載網(wǎng)站的本地副本并進(jìn)行爬取,確保每個(gè)頁面只訪問站點(diǎn)一次,這可以考慮使用開源軟件Wget以命令行的方式獲取網(wǎng)絡(luò)文件。64動(dòng)態(tài)網(wǎng)頁內(nèi)容爬取2024/5/1165動(dòng)態(tài)HTML介紹1.JavaScriptJavaScript是網(wǎng)絡(luò)上最常用、支持者最多的客戶端腳本語言。它可以收集用戶的跟蹤數(shù)據(jù),不需要重載頁面,直接提交表單,在頁面嵌入多媒體文件甚至運(yùn)行網(wǎng)頁游戲。在網(wǎng)頁源代碼的<script>標(biāo)簽里可以看到定義的JavaScript腳本語言,比如:66<scripttype="text/javascript"src="/w/mini/static_2015/js/sea.js?v=201601150944"></script>動(dòng)態(tài)HTML介紹2.jQueryjQuery是一個(gè)十分常見的庫,約70%最流行的網(wǎng)站(約200萬)和約30%的其他網(wǎng)站都在使用。一個(gè)網(wǎng)站使用jQuery的特征,就是源代碼里包含jQuery入口,比如:如果在一個(gè)網(wǎng)站上看到了jQuery,那么采集這個(gè)網(wǎng)站的數(shù)據(jù)時(shí)要格外小心。jQuery可以動(dòng)態(tài)地創(chuàng)建HTML內(nèi)容,只有在JavaScript代碼執(zhí)行之后才會顯示。如果使用傳統(tǒng)的方法采集頁面內(nèi)容,就只能獲得JavaScript代碼執(zhí)行之前的頁面內(nèi)容。67<scripttype="text/javascript"src="/w/mini/static_2015/js/jquery-1.11.1.min.js?v=201512181512"></script>動(dòng)態(tài)HTML介紹3.Ajax我們與網(wǎng)站服務(wù)器通信的唯一方式就是發(fā)出HTTP請求獲取新頁面。如果提交表單或從服務(wù)器獲取信息之后,網(wǎng)站的頁面不需要重新刷新,那么我們訪問的網(wǎng)站就使用了異步JavaScript和XML(asynchronousJavaScriptandXML,Ajax)技術(shù)。Ajax其實(shí)并不是一門語言,而是用來完成網(wǎng)絡(luò)任務(wù)(可以認(rèn)為它與網(wǎng)絡(luò)數(shù)據(jù)采集類似)的一系列技術(shù)。網(wǎng)站不需要使用單獨(dú)的頁面請求就可以和網(wǎng)絡(luò)服務(wù)器進(jìn)行交互(收發(fā)信息)。4.DHTML與Ajax相同,動(dòng)態(tài)HTML(dynamicHTML,DHTML)也是一系列用于解決網(wǎng)絡(luò)問題的技術(shù)的集合。DHTML使用客戶端語言改變頁面的HTML元素(HTML、css或兩者皆被改變)。比如,頁面上的按鈕只有當(dāng)用戶移動(dòng)鼠標(biāo)之后才會出現(xiàn),背景色可能每次點(diǎn)擊都會改變,或者用一個(gè)Ajax請求觸發(fā)頁面來加載一段新內(nèi)容。網(wǎng)頁是否屬于DHTML,關(guān)鍵要看是否使用JavaScript控制HTML和css元素。68動(dòng)態(tài)HTML介紹5.如何讀取DHTML使用Ajax或DHTML技術(shù)改變/加載內(nèi)容的頁面,可以用Python讀取,具體包括以下兩種途徑:(1)直接從JavaScript代碼里采集內(nèi)容(費(fèi)時(shí)費(fèi)力)。(2)用Python的第三方庫運(yùn)行JavaScript,直接采集在瀏覽器里看到的頁面。69Selenium基本應(yīng)用Selenium介紹Selenium是一個(gè)Web的自動(dòng)化測試工具,最初是為網(wǎng)站自動(dòng)化測試而開發(fā)的,類型像我們玩游戲用的按鍵精靈,可以按指定的命令自動(dòng)操作,不同是Selenium可以直接運(yùn)行在瀏覽器上,它支持所有主流的瀏覽器(包括PhantomJS這些無界面的瀏覽器)。Selenium可以根據(jù)我們的指令,讓瀏覽器自動(dòng)加載頁面,獲取需要的數(shù)據(jù),甚至頁面截屏,或者判斷網(wǎng)站上某些動(dòng)作是否發(fā)生。Selenium自己不帶瀏覽器,不支持瀏覽器的功能,它需要與第三方瀏覽器結(jié)合在一起才能使用。但是我們有時(shí)候需要讓它內(nèi)嵌在代碼中運(yùn)行,所以我們可以用一個(gè)叫PhantomJS的工具代替真實(shí)的瀏覽器PhantomJS是一個(gè)基于Webkit的“無界面”(headless)瀏覽器,它會把網(wǎng)站加載到內(nèi)存并執(zhí)行頁面上的JavaScript,因?yàn)椴粫故緢D形界面,所以運(yùn)行起來比完整的瀏覽器要高效。如果我們把Selenium和PhantomJS結(jié)合在一起,就可以運(yùn)行一個(gè)非常強(qiáng)大的網(wǎng)絡(luò)爬蟲了,這個(gè)爬蟲可以處理JavaScript、Cookie、headers,以及任何我們真實(shí)用戶需要做的事情。注意:PhantomJS只能從它的官方網(wǎng)站/download.html)下載70Selenium基本應(yīng)用(2)其他具體瀏覽器驅(qū)動(dòng)。第三方瀏覽器廠商一般會提供相應(yīng)的驅(qū)動(dòng)程序,如Chrome、Edge、Firefox等。下面以Windows平臺自帶的Edge瀏覽器為例說明如何安裝相應(yīng)的驅(qū)動(dòng)程序。首先,查看一下本地計(jì)算機(jī)Windows操作系統(tǒng)的內(nèi)部版本號,以Windows10為例,步驟為:依次單擊“開始”→“設(shè)置”→“系統(tǒng)”→“關(guān)于”,找到如圖所示的操作系統(tǒng)內(nèi)部版本號。然后,打開網(wǎng)址/en-us/microsoft-edge/tools/webdriver/,下載合適版本的驅(qū)動(dòng),并放到Python安裝目錄下或者當(dāng)前程序的目錄下。71Selenium基本應(yīng)用Selenium庫里有個(gè)叫WebDriver的API。WebDriver有點(diǎn)兒像可以加載網(wǎng)站的瀏覽器,但是它也可以像BeautifulSoup或者其他Selector對象一樣用來查找頁面元素,與頁面上的元素進(jìn)行交互(發(fā)送文本、點(diǎn)擊等),以及執(zhí)行其他動(dòng)作來運(yùn)行網(wǎng)絡(luò)爬蟲。使用Python調(diào)用Selenium框架執(zhí)行JavaScript腳本也可以將JavaScript的執(zhí)行結(jié)果返回給Python的一個(gè)對象,對象類型是WebElement,只需要在調(diào)用的JavaScript腳本中使用return語句返回對應(yīng)的內(nèi)容即可。需要注意的是,對于動(dòng)態(tài)網(wǎng)頁,可能不會正常獲取JavaScript動(dòng)態(tài)生成的內(nèi)容,從而導(dǎo)致解析失敗,必要時(shí)可以使用driver.execute_script方法執(zhí)行JavaScript腳本。72Selenium基本應(yīng)用例

使用selenium編寫爬蟲程序,獲取指定城市的當(dāng)前天氣。第1步首先,查看一下本地計(jì)算機(jī)Windows操作系統(tǒng)的內(nèi)部版本號,以我的Win10為例,步驟為:依次單擊開始==>設(shè)置==>系統(tǒng)==>關(guān)于,找到下圖中的操作系統(tǒng)內(nèi)部版本號:73Selenium基本應(yīng)用第2步打開網(wǎng)址/en-us/microsoft-edge/tools/webdriver/,下載合適版本的驅(qū)動(dòng),并放到Python安裝目錄下。第3步打開命令提示符環(huán)境,使用pip安裝擴(kuò)展庫selenium。第4步編寫如下程序代碼:importrefromseleniumimportwebdriver#指定引擎driver=webdriver.Edge()city=input('請輸入要查詢的城市:').lower()#獲取指定URL的信息,并進(jìn)行渲染driver.get(r'/find?q={0}'.format(city))#網(wǎng)頁內(nèi)容渲染結(jié)束之后獲取網(wǎng)頁源代碼,并轉(zhuǎn)換成小寫content=driver.page_source.lower()matchResult=re.search(r'<ahref="(.+?)">\s+'+city+'.+?]',content)ifmatchResult:print(matchResult.group(0))else:print('查不到,請檢查城市名字。')74網(wǎng)站操作模擬不同網(wǎng)站的登錄方式和網(wǎng)頁設(shè)計(jì)可能會發(fā)生變化,導(dǎo)致網(wǎng)站的手工操作模擬失敗。1.網(wǎng)站模擬登錄通過driver.find_element_by_name方法找到對應(yīng)元素,然后調(diào)用send_keys方法模擬手工輸入,或者執(zhí)行click方法模擬鼠標(biāo)點(diǎn)擊。示例程序如下:75fromseleniumimportwebdriverfrommon.keysimportKeysimporttimedriver=webdriver.PhantomJS()driver.get("")#輸入賬號和密碼driver.find_element_by_name("form_email").send_keys("xxxxx@")driver.find_element_by_name("form_password").send_keys("xxxxxxxx")#模擬點(diǎn)擊登錄driver.find_element_by_xpath("http://input[@class=bn-submit]").click()#等待3秒time.sleep(3)#生成登錄后的快照driver.save_screenshot("douban.png")withopen("douban.html","w")asfile:file.write(driver.page_source)driver.quit()網(wǎng)站操作模擬2.執(zhí)行JavaScript語句通過driver的execute_script方法執(zhí)行JavaScript語句。示例程序如下:76fromseleniumimportwebdriverdriver=webdriver.PhantomJS()driver.get("/")#給搜索輸入框標(biāo)紅的javascript腳本js="varq=document.getElementById(\"kw\");q.style.border=\"2pxsolidred\";"#調(diào)用給搜索輸入框標(biāo)紅的js腳本driver.execute_script(js)#查看頁面快照driver.save_screenshot("redbaidu.png")#js隱藏元素,將獲取的圖片元素隱藏img=driver.find_element_by_xpath("http://*[@id=lg]/img")driver.execute_script($(arguments[0]).fadeOut(),img)#向下滾動(dòng)到頁面底部driver.execute_script("$(.scroll_top).click(function(){$(html,body).animate({scrollTop:0px},800);});")#查看頁面快照driver.save_screenshot("nullbaidu.png")driver.quit()爬蟲框架Scrapy與應(yīng)用2024/5/1177scrapy爬蟲概述

Scrapy是一個(gè)使用Python語言編寫的開源網(wǎng)絡(luò)爬蟲框架,是一個(gè)高級的Python爬蟲框架。Scrapy可用于各種有用的應(yīng)用程序,如數(shù)據(jù)挖掘、信息處理以及歷史歸檔等,目前主要用于抓取Web站點(diǎn)并從頁面中提取結(jié)構(gòu)化的數(shù)據(jù)。

安裝方式:pipinstallscrapy。如果失敗,需要根據(jù)錯(cuò)誤提示分別按照順序安裝依賴的模塊,如twisted、lxml、erface、pywin32、pyOpenSSL等安裝完成后,用以下命令測試是否成功。Scrapy原理

Scrapy框架由ScrapyEngine、Scheduler、Downloader、Spiders、ItemPipeline、Downloadermiddlewares以及Spidermiddlewares等幾部分組成Scrapy原理在整個(gè)框架組成中,Spiders是最核心的組件,Scrapy爬蟲開發(fā)基本上圍繞Spiders而展開的。

此外,在Scrapy框架中還有三種數(shù)據(jù)流對象,分別是Request、Response和Items。Request是Scrapy中的HTTP請求對象。Response是Scrapy中的HTTP響應(yīng)對象。Item是種簡單的容器,用于保存爬取得到的數(shù)據(jù)。Scrapy原理Scrapy原理Request對象Request對象用于描述一個(gè)HTTP請求,由Spider產(chǎn)生,Request構(gòu)造函數(shù)的參數(shù)列表如下:Request(url[,callback,method='GET',headers,body,cookies,meta,encoding='utf-8',priority=0,dont_filter=False,errback])Response對象Response對象用于描述一個(gè)HTTP響應(yīng),由Downloader產(chǎn)生,Response構(gòu)造函數(shù)的參數(shù)列表如下:Response(url[,status=200,headers=None,body=b'',flags=None,request=None])Scrapy原理Select對象:

Scrapy的數(shù)組組織結(jié)構(gòu)是Selector,它使用xpath選擇器在Response中提取數(shù)據(jù)。從頁面中提取數(shù)據(jù)的核心技術(shù)是HTTP文本解析,在Python中常用的處理模塊有:BeautifulSoup

:是一個(gè)非常流行的解析庫,API簡單,但解析的速度慢。lxml

:是一個(gè)使用C語言編寫的xml解析庫,解析速度快,API相對比較復(fù)雜。Scrapy中的Selector對象是基于lxml庫建立的,并且簡化了API接口,使用方便。在具體實(shí)現(xiàn)中,Scrapy使用css和xpath選擇器來定位元素,它的基本方法如下:xpath():返回選擇器列表,每個(gè)選擇器代表使用xpath語法選擇的節(jié)點(diǎn)。css():返回選擇器列表,每個(gè)選擇器代表使用css語法選擇的節(jié)點(diǎn)。Scrapy原理response.xpath('/html/body/div')#選取

溫馨提示

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

評論

0/150

提交評論