版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領
文檔簡介
微課版
第2版Python爬蟲項目教程6目錄CONTENTS項目任務介紹01selenium編寫爬蟲程序02selenium查找HTML元素03selenium實現(xiàn)用戶登錄04selenium爬取Ajax網(wǎng)頁數(shù)據(jù)05selenium等待HTML元素06綜合項目
爬取模擬商城網(wǎng)站數(shù)據(jù)07實戰(zhàn)項目
爬取實際商城網(wǎng)站數(shù)據(jù)08爬取商城網(wǎng)站數(shù)據(jù)01商城網(wǎng)站項目任務01瀏覽器進入京東商城網(wǎng)站,在關鍵字輸入框輸入"手機"后回車可以看到圖6-1-1所示的頁面(注:圖示頁面僅做展示,實際略有不同),分析京東商城的網(wǎng)頁發(fā)現(xiàn)很多數(shù)據(jù)是JavaScript控制的,項目將使用selenium設計一個爬蟲程序爬取所有的手機數(shù)據(jù)與圖像。圖6-1-1京東商城網(wǎng)站圖6-1-3商城模擬網(wǎng)站圖6-1-2手機圖像商城網(wǎng)站項目任務01在爬取這個網(wǎng)站數(shù)據(jù)之前先學習爬取模擬網(wǎng)站的數(shù)據(jù)。創(chuàng)建一個project6的項目,在project6文件夾中有一個phones.csv文件,存儲了手機的數(shù)據(jù),前面幾行如下。其中每行都是一款手機的數(shù)據(jù),各個段之間用逗號","分開,第一段為ID編號,第二段是品牌,第三段是價格,第四段是說明,第五段是圖像名稱。在project6\images文件夾中存儲了各個手機的圖像,如圖6-1-2所示。使用phones.csv的數(shù)據(jù)建立一個手機商城網(wǎng)站,如圖6-1-3所示,其中網(wǎng)頁的很多數(shù)據(jù)是JavaScript控制的,例如各個翻頁按鈕是<inputtype='button'>按鈕,單擊按鈕時執(zhí)行對應的JavaScript函數(shù)實現(xiàn)翻頁。項目將使用selenium設計一個爬蟲程序爬取這個模擬網(wǎng)站的所有的手機數(shù)據(jù)與圖像。ID,mMark,mPrice,mNote,mImage000001,榮耀9i,1198.0,榮耀9i4GB+64GB幻夜黑
移動聯(lián)通電信4G全面屏手機
雙卡雙待,000001.jpg000002,榮耀8X,1399.0,榮耀8X千元屏霸91%屏占比2000萬AI雙攝4GB+64GB幻夜黑
移動聯(lián)通電信4G全面屏
雙卡雙待,000002.jpg000003,小米8,2299.0,小米8全面屏游戲智能手機6GB+64GB藍色
全網(wǎng)通4G雙卡雙待,000003.jpgselenium編寫爬蟲程序022.1JavaScript控制網(wǎng)頁2.2普通爬蟲程序的問題2.3安裝selenium框架2.4編寫selenium爬蟲程序2.1JavaScript控制網(wǎng)頁網(wǎng)頁上的信息不一定都是靜態(tài)的HTML數(shù)據(jù),實際上很多信息是通過JavaScript處理后得到的,那么怎么樣去爬取這些數(shù)據(jù)呢?我們先來設計一個包含JavaScript的網(wǎng)頁文檔,看看怎么樣爬取它的數(shù)據(jù)。1.創(chuàng)建網(wǎng)頁模板<script>window.onload=function(){http=newXMLHttpRequest();http.open("get","/show",false);http.send(null);msg=http.responseText;document.getElementById("sMsg").innerHTML=msg;document.getElementById("jMsg").innerHTML="javascriptMessage";}</script><body>Testing<br><spanid="hMsg">HtmlMessage</span><br><spanid="jMsg"></span><br><spanid="sMsg"></span></body>2.1JavaScript控制網(wǎng)頁importflaskapp=flask.Flask(__name__)@app.route("/")defindex():returnflask.render_template("phone.html")@app.route("/show")defshow():return"ServerMessage"app.run()2.創(chuàng)建服務器程序服務器程序server.py顯示出phone.html文件的內(nèi)容,其中index()函數(shù)讀取該文件并發(fā)送出去,show()函數(shù)是在接受地址"/show"請求后發(fā)送"ServerMessage"。2.2普通爬蟲程序的問題frombs4importBeautifulSoupimporturllib.requestresp=urllib.request.urlopen(":5000");html=resp.read()html=html.decode()soup=BeautifulSoup(html,"lxml")hMsg=soup.find("span",attrs={"id":"hMsg"}).textprint(hMsg)jMsg=soup.find("span",attrs={"id":"jMsg"}).textprint(jMsg)sMsg=soup.find("span",attrs={"id":"sMsg"}).textprint(sMsg)1.編寫普通爬蟲程序設計一個爬蟲程序spider.py,它通過urllib.request直接訪問":5000"獲取HTML代碼,使用BeautifulSoup解析得到數(shù)據(jù),程序如下。執(zhí)行該程序結(jié)果如下。HtmlMessage顯然如果我們通過該方法獲取網(wǎng)頁HTML文檔然后進行數(shù)據(jù)爬取,那么只能爬取hMsg的信息"HTMLMessage",但是爬取不到jMsg與sMsg的信息!因為jMsg與sMsg的信息不是靜態(tài)地嵌入在網(wǎng)頁中的,而是通過JavaScript與Ajax動態(tài)產(chǎn)生的,通過urllib.request.urlopen得到的網(wǎng)頁中沒有這樣的動態(tài)信息,如果要得到這些信息就必須讓爬蟲程序能夠執(zhí)行對應的JsvaScript程序,下面介紹的selenium框架有這個功能。2.3安裝selenium框架前面已經(jīng)分析了要獲取jMsg與sMsg的這些信息就必須在獲取網(wǎng)頁后客戶端能按要求執(zhí)行對應的JavaScript程序。顯然一般的客戶端程序沒有這個能力去執(zhí)行JavaScript程序,我們必須尋找一個能像瀏覽器那樣工作的插件來完成這個工作,它就是selenium。selenium就是一個沒有顯示界面的瀏覽器,它能與通用的瀏覽器(如Chrome、Firefox等)配合工作。我們要先安裝selenium與Chrome的驅(qū)動程序。pipinstallselenium(1)安裝selenium
執(zhí)行該命令即可完成安裝。(2)安裝Chrome驅(qū)動程序要selenium與瀏覽器配合工作就必須安裝瀏覽器對應的驅(qū)動程序,例如要與Chrome配合就要先下載chromedrive.exe的驅(qū)動程序,而且保證Chrome瀏覽器與chromedriver.exe的版本一致。在Chrome中輸入"chrome://version"檢測目前瀏覽器版本,目前使用版本是126.0.6478.182,如圖6-2-2所示。然后下載適合這個Chrome版本的chromedriver.exe,下載完成后直接運行這個驅(qū)動程序可以看到它的版本,如圖6-2-3所示,確保chromedriver.exe版本與Chrome的一致。然后把chromedriver.exe它復制到Python的scripts目錄下。圖6-2-2Chrome瀏覽器版本圖6-2-3驅(qū)動程序版本2.4編寫selenium爬蟲程序1.編寫selenium爬蟲程序selenium模擬瀏覽器訪問網(wǎng)站的方法來獲取網(wǎng)頁文檔,然后從中爬取需要的數(shù)據(jù),這樣的爬蟲程序功能就比較強大了,設計爬蟲程序spider.py如下。fromseleniumimportwebdriverfromselenium.webdriver.chrome.optionsimportOptionsfrombs4importBeautifulSoupoptions=Options()options.add_argument('--headless')options.add_argument('--disable-gpu')driver=webdriver.Chrome(options=options)driver.get(":5000")html=driver.page_sourcesoup=BeautifulSoup(html,"lxml")hMsg=soup.find("span",attrs={"id":"hMsg"}).textprint(hMsg)jMsg=soup.find("span",attrs={"id":"jMsg"}).textprint(jMsg)sMsg=soup.find("span",attrs={"id":"sMsg"}).textprint(sMsg)HtmlMessagejavascriptMessageServerMessageselenium查找HTML元素033.1創(chuàng)建商城模擬網(wǎng)站3.2使用xpath查找元素3.3查找元素的文本與屬性3.4使用id查找元素3.5使用name查找元素3.6使用CSS查找元素3.7使用tagName查找元素3.8使用文本查找超級鏈接3.9使用class查找元素3.1創(chuàng)建商城模擬網(wǎng)站1.創(chuàng)建網(wǎng)站模板在templates文件夾中設計一個phone.html,內(nèi)容如下。<style>.pic{display:inline-block;width:200px;vertical-align:top;margin:10px;}.info{display:inline-block;width:500px;}.title{}.price{margin:10px;color:red;}h3{display:inline-block;}}.pl{color:#888;}.author{}.date{}.detail{}</style><div><divclass="pic"><imgwidth="200"id="image"src='/images/000001.jpg'></div><divclass="info"><divclass="title"><h3id="title"style="display:inline-block">榮耀9i</h3></div><divclass="mark"><spanclass="pl">品牌</span>:<spanname="mark">華為</span></div><divclass="date"><spanclass="pl">生產(chǎn)日期</span>:<spanname="date">2016-12-01</span></div><divclass="price"><spanclass="pl">價格</span>:<spanname="price">¥1200.00</span></div><div>簡介:</div><divclass="detail">
榮耀9i4GB+64GB幻夜黑<ahref="#">移動聯(lián)通</a>電信4G全面屏手機<ahref="#">雙卡雙待</a></div></div></div>3.1創(chuàng)建商城模擬網(wǎng)站2.創(chuàng)建網(wǎng)站服務器創(chuàng)建一個服務器server.py用來展示phone.html網(wǎng)頁,程序如下。執(zhí)行這個服務器程序,使用瀏覽器瀏覽":5000",結(jié)果如圖6-3-1所示。importflaskapp=flask.Flask(__name__,static_folder="images",static_url_path="/images")@app.route("/")defshow():returnflask.render_template("phone.html")app.run()圖6-3-1商城網(wǎng)站3.1創(chuàng)建商城模擬網(wǎng)站3.創(chuàng)建查找程序selenium搭配有很多種查找HTML元素的方法,通過這些方法就可以爬取到所要的數(shù)據(jù),為了方便說明,先設計下列程序:fromseleniumimportwebdriverfromselenium.webdriver.chrome.optionsimportOptionsfrommon.byimportByoptions=Options()options.add_argument('--headless')options.add_argument('--disable-gpu')driver=webdriver.Chrome(options=options)driver.get(":5000")#查找元素與數(shù)據(jù)driver.close()3.2使用xpath查找元素elem=driver.find_element(by=By.XPATH,value="http://div[@class='info']//h3")print(type(elem))使用xpath查找主要有兩個函數(shù):(1)函數(shù)find_element(by=By.XPATH,value=xpath)查找xpath匹配的第一個元素,如果找到就返回一個WebElement類型的對象,如果找不到就拋出異常;(2)函數(shù)find_elements(by=By.XPATH,value=xpath):查找xpath匹配的所有元素組成的列表,每個元素都是一個WebElement對象,如果找不到就返回空列表;任何一個WebElement對象都可以調(diào)用find_element(by=By.XPATH,value=)與find_elements(by=By.XPATH,value=)函數(shù)。例6-3-1:查找網(wǎng)頁元素<h3><class'selenium.webdriver.remote.webelement.WebElement'>例6-3-2:查找網(wǎng)頁中元素<h4>結(jié)果發(fā)現(xiàn)沒有找到<h4>,拋出下列異常錯誤信息:try:elem=driver.find_element(by=By.XPATH,value="http://div[@class='info']//h4")print(type(elem))exceptExceptionaserr:print(err)Message:nosuchelement:Unabletolocateelement:{"method":"xpath","selector":"http://div[@class='info']//h4"}3.3查找元素的文本與屬性print(driver.find_element(by=By.XPATH,value="http://div[@class='info']//span").text)通過WebElement對象可以查找到它的文本與屬性。(1)任何一個WebElement對象都可以通過text屬性獲取它的文本,元素的文本值是它與它的所有子孫節(jié)點的文字的組合,如果沒有就返回空字符串。(2)任何一個WebElement對象都可以通過get_attribute(attrName)獲取名稱為attrName的屬性值,如果元素沒有attrName屬性就返回None。例6-3-3:查找網(wǎng)頁中第一個<span>元素的文本品牌結(jié)果:elem=driver.find_element(by=By.XPATH,value="http://div[@class='mark']")elems=elem.find_elements(by=By.XPATH,value=".//span")foreleminelems:print(elem.text)例6-3-4:查找網(wǎng)頁中<divclass='mark'>中所有<span>元素的文本品牌華為結(jié)果:3.3查找元素的文本與屬性print(driver.find_element(by=By.XPATH,value="http://div[@class='info']//span[@name='mark']").text)例6-3-5:查找網(wǎng)頁中手機的品牌華為結(jié)果:elem=driver.find_element(by=By.XPATH,value="http://div[@class='pic']//img").get_attribute("alt")print(type(elem),len(elem))elem=driver.find_element(by=By.XPATH,value="http://div[@class='pic']//img").get_attribute("xxx")print(elem)例6-3-7:查找網(wǎng)頁中手機圖像<img>的alt屬性與xxx屬性<class'str'>0None結(jié)果:print(driver.find_element(by=By.XPATH,value="http://div[@class='pic']//img").get_attribute("src"))例6-3-6:查找網(wǎng)頁中手機圖像<img>的地址:5000/images/000001.jpg結(jié)果:elem=driver.find_element(by=By.XPATH,value="http://div[@class='mark']")print("innerHTML")print(elem.get_attribute("innerHTML").strip())print("outerHTML")print(elem.get_attribute("outerHTML").strip())例6-3-8:查找網(wǎng)頁中<divclass='mark'>的HTML文本innerHTML<spanclass="pl">品牌</span>:<spanname="mark">華為</span>outerHTML<divclass="mark"><spanclass="pl">品牌</span>:<spanname="mark">華為</span><div>結(jié)果:3.4使用id查找元素print(driver.find_element(by=By.ID,value="title").text)HTML中很多元素都有一個唯一的id值,selenium可以通過id值查找到元素。函數(shù)driver.find_element(by=By.ID,value=id)查找id編號的第一個元素,如果查找到就返回一個WebElement對象,如果沒有找到就拋出異常。例6-3-9:查找網(wǎng)頁中id="title"的元素文本榮耀9i結(jié)果:try:print(driver.find_element(by=By.ID,value="name"))exceptExceptionaserr:print(err)例6-3-10:查找網(wǎng)頁中id="name"的元素Message:nosuchelement:Unabletolocateelement:{"method":"id","selector":"name"}結(jié)果拋出一個異常:3.5使用name查找元素print(driver.find_element(by=By.NAME,value="mark").text)HTML中很多元素都有一個name屬性值,selenium可以通過name屬性值查找到元素。(1)函數(shù)find_element(by=By.NAME,value=name):查找name匹配的第一個元素,如果找到就返回一個WebElement類型的對象,如果找不到就拋出異常;(2)函數(shù)find_elements(by=By.NAME,value=value):查找name=value匹配的所有元素組成的列表,每個元素都是一個WebElement對象,如果找不到就返回空列表;例6-3-11:查找網(wǎng)頁中手機品牌華為結(jié)果:try:driver.find_element(by=By.NAME,value="xxx")exceptExceptionaserr:print(err)例6-3-12:查找網(wǎng)頁name="xxx"的元素Message:nosuchelement:Unabletolocateelement:{"method":"name","selector":"xxx"}結(jié)果拋出一個異常:3.6使用CSS查找元素print(driver.find_element(by=By.CSS_SELECTOR,value="div[class='info']span[name='mark']").text)selenium也支持CSS語法查找元素。(1)函數(shù)find_element(by=By.CSS_SELECTOR,value=css):查找css匹配的第一個元素,如果找到就返回一個WebElement類型的對象,如果找不到就拋出異常;(2)函數(shù)find_elements(by=By.CSS_SELECTOR,value=css):查找css匹配的所有元素組成的列表,每個元素都是一個WebElement對象,如果找不到就返回空列表。例6-3-13:查找網(wǎng)頁中手機品牌華為結(jié)果:elems=driver.find_elements(by=By.CSS_SELECTOR,value="div[class='mark']*")foreleminelems:print(elem.text)例6-3-15:查找網(wǎng)頁中<divclass='mark'>下面的所有元素或者:print(driver.find_element(by=By.CSS_SELECTOR,value="div[class='pic']>img").get_attribute("src"))例6-3-14:查找網(wǎng)頁中手機圖像地址:5000/images/000001.jpg結(jié)果:品牌華為結(jié)果:榮耀9iprint(driver.find_element(by=By.CSS_SELECTOR,value="#title").text)例6-3-16:查找網(wǎng)頁中手機型號print(driver.find_element(by=By.CSS_SELECTOR,value="[id='title']").text)結(jié)果:3.7使用tagName查找元素print(driver.find_element(by=By.TAG_NAME,value="h3").text)elenium還可以通過HTML元素的tagName查找。函數(shù)find_elements(by=By.TAG_NAME,value=tagName):查找tagName匹配的所有元素,如果找到就返回一個WebElement列表,如果找不到列表為空。例6-3-18:查找網(wǎng)頁中手機型號榮耀9i結(jié)果:elem=driver.find_element(by=By.XPATH,value="http://div[@class='mark']")elems=elem.find_elements(by=By.TAG_NAME,value="span")foreleminelems:print(elem.text)例6-3-17:查找<divclass='mark'>元素下面的所有<span>元素品牌華為結(jié)果:3.8使用文本查找超級鏈接selenium可以通過超級鏈接的文本來查找到該超級鏈接。(1)函數(shù)find_element(by=By.LINK_TEXT,value=text)查找第一個文本值為text的超級鏈接元素<a>,如果找到就返回該元素的WebElement對象,如果找不到就拋出異常。(2)函數(shù)find_element(by=By.PARTIAL_LINK_TEXT,value=text)查找第一個文本值包含text的超級鏈接元素<a>,如果找到就返回該元素的WebElement對象,如果找不到就拋出異常。(3)函數(shù)find_elements(by=By.LINK_TEXT,value=text)查找所有文本值為text的超級鏈接元素<a>,如果找到就返WebElement列表,如果找不到列表為空。(4)函數(shù)find_elements(by=By.PARTIAL_LINK_TEXT,value=text)查找所有文本值包含text的超級鏈接元素<a>,果找到就返WebElement列表,如果找不到列表為空。print(driver.find_element(by=By.XPATH,value="http://div[@class='detail']/a").text)print(driver.find_element(by=By.LINK_TEXT,value="移動聯(lián)通").text)print(driver.find_element(by=By.PARTIAL_LINK_TEXT,value="移動").text)print(driver.find_element(by=By.PARTIAL_LINK_TEXT,value="動聯(lián)").text)例6-3-19:查找網(wǎng)頁<ahref="#">移動聯(lián)通<a>元素移動聯(lián)通移動聯(lián)通移動聯(lián)通移動聯(lián)通這幾種方法都能找到,結(jié)果:3.9使用class查找超級鏈接selenium可以使用元素的class值查找元素。(1)函數(shù)find_element(by=By.CLASS_NAME,value=value)查找第一個class=value的元素,如果找到就返回該元素的WebElement對象,如果找不到就拋出異常。(2)函數(shù)find_elements(by=By.CLASS_NAME,value=value)查找所有class=value元素,如果找到就返WebElement列表,如果找不到列表為空。elems=driver.find_elements(by=By.CLASS_NAME,value="pl")foreleminelems:print(elem.text)例6-3-20:查找網(wǎng)頁class="pl"的所有元素品牌生產(chǎn)日期價格結(jié)果:顯然也可以通過下列方式查找:elems=driver.find_elements(by=By.XPATH,value="http://*[@class='pl']")elems=driver.find_elements(by=By.CSS_SELECTOR,value="*[class='pl']")selenium實現(xiàn)用戶登錄044.1創(chuàng)建用戶登錄網(wǎng)站4.2使用元素動作4.3編寫爬蟲程序4.1創(chuàng)建用戶登錄網(wǎng)站1.創(chuàng)建網(wǎng)站模板很多網(wǎng)站都需要用戶登錄后才能訪問到其他網(wǎng)頁,在templates中創(chuàng)建一個login.html的用戶登錄網(wǎng)頁模板文件,在啟動時顯示登錄界面,用戶輸入名稱(假定是"xxx")及密碼(假定是"123")后就完成登錄,然后轉(zhuǎn)去"/show"的頁面,顯示出手機的記錄。login.html內(nèi)容如下。<body><formid="frm"action="/"method="post"><div>用戶<inputtype="text"name="user"id="user"></div><div>密碼<inputtype="password"name="pwd"id="pwd"></div><div><inputtype="submit"name="login"id="login"vaule='登錄'></div></form></body>4.1創(chuàng)建用戶登錄網(wǎng)站2.創(chuàng)建服務器程序服務器程序server.py首先提交一個login.html的網(wǎng)頁,用戶輸入名稱與密碼后提交,服務器獲取用戶名稱與密碼后判斷是否正確,如果不正確就繼續(xù)顯示登錄頁面,如果正確就轉(zhuǎn)"/show"頁面顯示手機記錄,服務器程序如下。importflaskapp=flask.Flask(__name__)@app.route("/",methods=["GET","POST"])deflogin():user=flask.request.values.get("user")if"user"inflask.request.valueselse""pwd=flask.request.values.get("pwd")if"pwd"inflask.request.valueselse""ifuser=="xxx"andpwd=="123":returnflask.redirect("/show")else:returnflask.render_template("login.html")@app.route("/show",methods=["GET","POST"])defshow():s="<tableborder='1'>"s=s+"<tr><td>品牌</td><td>型號</td><td>價格</td></tr>"s=s+"<tr><td>華為</td><td>P9</td><td>3800</td></tr>"s=s+"<tr><td>華為</td><td>P10</td><td>4200</td></tr>"s=s+"<tr><td>蘋果</td><td>iPhone6</td><td>5800</td></tr>"s=s+"</table><p>"s=s+"<ahref='/'>退出</a>"returnsapp.run()4.1創(chuàng)建用戶登錄網(wǎng)站3.瀏覽器瀏覽啟動服務器程序后瀏覽web地址":5000",結(jié)果如圖6-4-1與圖6-4-2所示,用戶登錄成功后就可以看到手機的記錄。圖6-4-1用戶登錄圖6-4-2登錄成功4.2使用元素動作1.鍵盤輸入動作有些元素例如<inputtype="text">文本輸入框是用戶可以輸入文字的,WebElement對象element可以模擬用戶的鍵盤輸入動作,主要動作有:(1)clear()函數(shù)模擬清除element元素中的所有文字;(2)send_keys(string)函數(shù)模擬鍵盤在元素中輸入字符串string;其中send_keys()函數(shù)不但可以模擬輸入一般的文字,而且還可以模擬輸入回車、退格等鍵盤動作,selenium提供了一個Keys類,提供了很多常用的不可見的特殊按鍵,例如,Keys.BACKSPACE退格刪除鍵和Keys.ENTER回車鍵。圖6-4-3實現(xiàn)鍵盤輸入4.2使用元素動作編寫下面的spider.py程序:fromseleniumimportwebdriverimporttimetry:driver=webdriver.Chrome()driver.get(":5000")user=driver.find_element(by=By.NAME,value="user")pwd=driver.find_element(by=By.NAME,value="pwd")time.sleep(0.5)user.send_keys("xxx")time.sleep(0.5)pwd.send_keys("123")exceptExceptionaserr:print(err)input("Strikeanykeytofinish...")driver.close()2.鼠標單擊動作很多HTML元素都有鼠標單擊動作,例如<inputtype="submit">提交按鈕單擊后就提交表單。WebElement使用click()函數(shù)實現(xiàn)鼠標單擊,例如:driver.find_element(by=By.XPATH,value=“input[@type=’submit’]”).click().4.3編寫爬蟲程序使用selenium模擬瀏覽器的瀏覽過程與用戶的登錄過程,然后爬取手機的記錄,程序過程如下。(1)創(chuàng)建一個瀏覽器對象driver,使用這個driver對象模擬瀏覽器。(2)訪問:5000網(wǎng)站,獲取<inputtype="text"name="user">與<inputtype="password"name="pwd">元素對象,模擬用戶鍵盤輸入名稱"xxx"與密碼“123”。(3)獲取<inputtype="submit"name="login">按鈕對象,執(zhí)行click()單擊動作提交表單。(4)服務器接收提交的user與pwd數(shù)據(jù),判斷是否登錄成功,如果登錄成功就轉(zhuǎn)"/show"頁面顯示手機記錄。(5)爬蟲程序爬取數(shù)據(jù)記錄。編寫爬蟲程序spider.py如下(第一部分)。fromseleniumimportwebdriverfromselenium.webdriver.chrome.optionsimportOptionsfrommon.byimportByimporttime.4.3編寫爬蟲程序編寫爬蟲程序spider.py如下(第二部分)。deflogin():print(driver.current_url)user=driver.find_element(by=By.NAME,value="user")pwd=driver.find_element(by=By.NAME,value="pwd")login=driver.find_element(by=By.NAME,value="login")user.send_keys("xxx")pwd.send_keys("123")login.click()time.sleep(0.5)defspider():print(driver.current_url)trs=driver.find_elements(by=By.TAG_NAME,value="tr")foriinrange(1,len(trs)):tds=trs[i].find_elements(by=By.TAG_NAME,value="td")iflen(tds)==3:mark=tds[0].textmodel=tds[1].textprice=tds[2].textprint("%-16s%-16s%-16s"%(mark,model,price))options=Options()options.add_argument('--headless')options.add_argument('--disable-gpu')driver=webdriver.Chrome(options=options)try:driver.get(":5000")login()spider()exceptExceptionaserr:print(err)driver.close()selenium爬取Ajax網(wǎng)頁數(shù)據(jù)055.1創(chuàng)建AJax網(wǎng)站5.2理解selenium爬蟲程序5.3編寫爬蟲程序5.1創(chuàng)建Ajax的網(wǎng)站1.創(chuàng)建網(wǎng)頁文件在templates文件夾中創(chuàng)建網(wǎng)頁文件phone.html,它的內(nèi)容如下。<script>functioninit(){varmarks=newArray("華為","蘋果","三星");varselm=document.getElementById("marks");for(vari=0;i<marks.length;i++){selm.options.add(newOption(marks[i],marks[i]));}selm.selectedIndex=0;display();}functiondisplay(){try{varhttp=newXMLHttpRequest();varselm=document.getElementById("marks");varm=selm.options[selm.selectedIndex].text;http.open("get","/phones?mark="+m,false);http.send(null);msg=http.responseText;obj=eval("("+msg+")");for(vari=0;i<obj.phones.length;i++){s=s+"<tr><td>"+obj.phones[i].model+"</td><td>"+obj.phones[i].price+"</td></tr>";}s=s+"</table>";document.getElementById("phones").innerHTML=s;}catch(e){alert(e);}}</script><bodyonload="init()"><div>選擇品牌<selectid="marks"onchange="display()"></select></div><divid="phones"></div></body>5.1創(chuàng)建Ajax的網(wǎng)站2.創(chuàng)建服務器程序服務器程序server.py首先提交一個phone.html的網(wǎng)頁,然后響應"/phones?mark=..."的請求,根據(jù)mark的值確定品牌,返回該品牌下的手機記錄,返回的記錄采用JSON數(shù)據(jù)格式,服務器程序如下。importflaskimportjsonapp=flask.Flask(__name__)@app.route("/")defindex():returnflask.render_template("phone.html")@app.route("/phones")defgetPhones():mark=flask.request.values.get("mark")phones=[]ifmark=="華為":phones.append({"model":"P9","mark":"華為","price":3800})phones.append({"model":"P10","mark":"華為","price":4000})elifmark=="蘋果":phones.append({"model":"iPhone5","mark":"蘋果","price":5800})phones.append({"model":"iPhone6","mark":"蘋果","price":6800})elifmark=="三星":phones.append({"model":"GalaxyA9","price":2800})s=json.dumps({"phones":phones})returnsif__name__=="__main__":app.run()5.2理解selenium爬蟲程序但是selenium就不一樣,它是一個瀏覽器,在瀏覽一個網(wǎng)頁后會在它內(nèi)部構(gòu)建一棵HTML元素DOM網(wǎng)頁樹,編寫下列spider.py程序查看HTML代碼:fromseleniumimportwebdriverfromselenium.webdriver.chrome.optionsimportOptionsoptions=Options()options.add_argument('--headless')options.add_argument('--disable-gpu')driver=webdriver.Chrome(options=options)driver.maximize_window()driver.get(":5000")print(driver.page_source)driver.close()5.3編寫爬蟲程序使用Selenium模擬瀏覽器去瀏覽網(wǎng)頁,然后再模擬用戶選擇<select>中各個手機品牌的過程實現(xiàn)換頁,就可以逐頁爬取所有的手機數(shù)據(jù)了,爬蟲程序過程如下。(1)創(chuàng)建一個瀏覽器對象driver,使用這個driver對象模擬瀏覽器。(2)訪問:5000網(wǎng)站,爬取第一個頁面的手機數(shù)據(jù)。(3)從第一個頁面中獲取<select>中所有的選擇項目options。(4)循環(huán)options中的每個option,并模擬這個option的click單擊動作,觸發(fā)onchange事件調(diào)用display()函數(shù),爬取每個頁面的手機數(shù)據(jù)。根據(jù)這個規(guī)則,編寫爬蟲程序spider.py如下。frommon.byimportByfromseleniumimportwebdriverfromselenium.webdriver.chrome.optionsimportOptionsdefspider():trs=driver.find_elements(by=By.TAG_NAME,value="tr")foriinrange(1,len(trs)):tds=trs[i].find_elements(by=By.TAG_NAME,value="td")model=tds[0].textprice=tds[1].textprint("%-16s%-16s"%(model,price))options=Options()options.add_argument('--headless')options.add_argument('--disable-gpu')driver=webdriver.Chrome(options=options)driver.maximize_window()driver.get(":5000")select=driver.find_element(by=By.ID,value="marks")options=select.find_elements(by=By.TAG_NAME,value="option")foroptioninoptions:option.click()spider()driver.close()selenium等待HTML元素066.1創(chuàng)建延遲模擬網(wǎng)站6.2selenium強制等待6.3selenium隱式等待6.4selenium顯式等待6.1創(chuàng)建延遲模擬網(wǎng)站1.創(chuàng)建網(wǎng)頁模版在templates中創(chuàng)建一個phone.html,這個文件使用Ajax從服務器獲取手機的品牌放在一個<select>中,注意<select>中的<option>開始是不存在的,只有獲取數(shù)據(jù)后才產(chǎn)生,模板文件如下。<script>functionloadMarks(){varhttp=newXMLHttpRequest();http.onreadystatechange=function(){if(http.readyState==4&&http.status==200){varxmark=document.getElementById("xmark");marks=eval("("+http.responseText+")");for(vari=0;i<marks.length;i++)xmark.options.add(newOption(marks[i],marks[i]));document.getElementById("submit").disabled=false;
document.getElementById("msg").innerHTML="品牌}};http.open("get","/marks",true);http.send(null);}loadMarks();</script><body><formname="frm"action="/"><div><spanid="msg"></span><selectid="xmark"></select></div><inputtype="submit"value="提交"id="submit"disabled="true"></form></body>"6.1創(chuàng)建延遲模擬網(wǎng)站2.創(chuàng)建服務器程序網(wǎng)站服務器在訪問地址"/"時首先提交phone.html網(wǎng)頁,然后網(wǎng)頁中根據(jù)JavaScript代碼會執(zhí)行l(wèi)oadMarks()函數(shù),再次訪問服務器"/phones"時發(fā)送手機的品牌marks與顏色colors數(shù)據(jù),數(shù)據(jù)按JSON字符串格式發(fā)送。為了模擬延遲過程使用time.sleep(1)延遲1秒后發(fā)送數(shù)據(jù),服務器server.py程序如下。運行服務器并使用瀏覽器瀏覽結(jié)果,延遲一會后出現(xiàn)如圖6-6-2所示的網(wǎng)頁界面。importflaskimportjsonimporttimeapp=flask.Flask(__name__)@app.route("/")defindex():returnflask.render_template("phone.html")@app.route("/marks")defloadMarks():time.sleep(1)marks=["華為","蘋果","三星"]returnjson.dumps(marks)app.run()圖6-6-2延遲模擬網(wǎng)站6.2selenium強制等待selenium使用time.sleep(seconds)來實現(xiàn)強制等待seconds秒,這種方式是最簡單粗暴的方式,不管當前操作是否完成,是否可以進行下一步操作,都必須等seconds秒的時間。這個方法的優(yōu)點是簡單,缺點是不能準確把握需要等待的時間(有時操作還未完成,等待就結(jié)束了,導致報錯;有時操作已經(jīng)完成了,但等待時間還沒有到,浪費時間),如果在實際中大量使用,會浪費不必要的等待時間,影響測試用例的執(zhí)行效率。fromseleniumimportwebdriverfrommon.byimportByimporttimedriver=webdriver.Chrome()driver.get(":5000")#設置強制等待1.5秒time.sleep(1.5)marks=driver.find_elements(by=By.XPATH,value="http://select/option")print("品牌數(shù)量:",len(marks))formarkinmarks:print(mark.text)form=driver.find_element(by=By.XPATH,value="http://form")print(form.get_attribute("innerHTML").strip())time.sleep(5)driver.close()執(zhí)行結(jié)果:品牌數(shù)量:3華為蘋果三星<div>品牌<selectid="xmark"><optionvalue="華為">華為</option><optionvalue="蘋果">蘋果</option><optionvalue="三星">三星</option></select></div><inputtype="submit"value="提交"id="submit">6.3selenium隱式等待selenium使用implicitly_wait(seconds)設置隱式等待指定的秒數(shù),即網(wǎng)頁在加載時最長等待seconds秒,例如爬蟲程序在訪問網(wǎng)頁設置隱式載時間為1.5秒,spider.py程序如下。fromseleniumimportwebdriverimporttimedriver=webdriver.Chrome()#設置隱性加載時間1.5秒driver.implicitly_wait(1.5)driver.get(":5000")marks=driver.find_elements(by=By.XPATH,value="http://select/option")print("品牌數(shù)量:",len(marks))formarkinmarks:print(mark.text)form=driver.find_element(by=By.XPATH,value="http://form")print(form.get_attribute("innerHTML").strip())time.sleep(5)driver.close()執(zhí)行結(jié)果:品牌數(shù)量:3華為蘋果三星<div>品牌<selectid="xmark"><optionvalue="華為">華為</option><optionvalue="蘋果">蘋果</option><optionvalue="三星">三星</option></select></div><inputtype="submit"value="提交"id="submit">6.4selenium顯式等待1.循環(huán)等待實際上這個爬蟲程序能否爬到數(shù)據(jù)的關鍵是<select>中是否已經(jīng)出現(xiàn)了<option>元素,我們可以設置一個循環(huán)來判斷是否有<option>元素,程序spider.py修改如下。fromseleniumimportwebdriverimporttimedriver=webdriver.Chrome()try:driver.get(":5000")waitTime=0whilewaitTime<10:marks=driver.find_elements(by=By.XPATH,value="http://select/option")iflen(marks)>0:breaktime.sleep(0.5)waitTime+=0.5ifwaitTime>=10:raiseException("Waitingtimeout")
marks=driver.find_elements(by=By.XPATH,value="http://select/option")print("品牌數(shù)量:",len(marks))formarkinmarks:print(mark.text)form=driver.find_element(by=By.XPATH,value="http://form")print(form.get_attribute("innerHTML").strip())exceptExceptionaserr:print(err)time.sleep(5)driver.close()6.4selenium顯式等待2.顯式等待selenium的顯式等待與循環(huán)等待有點類似,它是專門等待指定的元素的。selenium使用WebDriverWait類來實現(xiàn)顯式等待,在使用顯式等待之前先引入WebDriverWait、EC以及By等類:fromselenium.webdriver.support.waitimportWebDriverWaitfromselenium.webdriver.supportimportexpected_conditionsasECfrommon.byimportBy然后構(gòu)造一個定位元素的locator的對象,例如,通過xpath的方法定位<select>中的<option>元素:locator=(By.XPATH,"http://select/option")最后使用WebDriverWait構(gòu)造一個實例,調(diào)用until方法:WebDriverWait(driver,10,0.5).until(EC.presence_of_element_located(locator))
這條語句的含義是等待locator指定的元素出現(xiàn),最長等待10秒,每間隔0.5秒就檢查一次。如果在10秒內(nèi)出現(xiàn)了該元素就結(jié)束等待,否則就繼續(xù)等待。如果超過10秒還沒有等待到locator要求的元素就拋出一個異常。6.4selenium顯式等待2.顯式等待使用顯式待的爬程序spider.py如下。fromseleniumimportwebdriverimporttimefromselenium.webdriver.support.waitimportWebDriverWaitfromselenium.webdriver.supportimportexpected_conditionsasECfrommon.byimportBydriver=webdriver.Chrome()try:driver.get(":5000")locator=(By.XPATH,"http://select/option")WebDriverWait(driver,10,0.5).until(EC.presence_of_element_located(locator))
marks=driver.find_elements(by=By.XPATH,value="http://select/option")print("品牌數(shù)量:",len(marks))formarkinmarks:print(mark.text)form=driver.find_element(by=By.XPATH,value="http://form")print(form.get_attribute("innerHTML").strip())exceptExceptionaserr:print(err)time.sleep(5)driver.close()綜合項目爬取模擬商城網(wǎng)站數(shù)據(jù)076.1創(chuàng)建商城模擬網(wǎng)站6.2設計存儲數(shù)據(jù)庫6.3編寫爬蟲程序7.1創(chuàng)建商城模擬網(wǎng)站1.創(chuàng)建網(wǎng)頁模板在templates中創(chuàng)建一個phone.html網(wǎng)頁模板如下。(第一部分)<style>.phone{display:inline-block;padding:10px10px10px10px;border:solid0px;width:200px;height:300px;vertical-align:text-top;text-align:left}</style><script>functionfirstPage(){window.location.href="/?pageIndex=1";}functionprevPage(){varpageIndex=parseInt(document.getElementById("pageIndex").value);pageIndex--;if(pageIndex>=1){window.location.href="/?pageIndex="+pageIndex;}}functionnextPage()}{varpageIndex=parseInt(document.getElementById("pageIndex").value);varpageCount=parseInt(document.getElementById("pageCount").value);pageIndex++;if(pageIndex<=pageCount){window.location.href="/?pageIndex="+pageIndex;}functionlastPage(){varpageCount=parseInt(document.getElementById("pageCount").value);
window.location.href="/?pageIndex="+pageCount;}</script>7.1創(chuàng)建商城模擬網(wǎng)站1.創(chuàng)建網(wǎng)頁模板在templates中創(chuàng)建一個phone.html網(wǎng)頁模板如下。(第二部分)<body><divstyle="text-align:center">{%forpinphones%}{%ifloop.index0isdivisibleby(rowItemCount)%}<divstyle="width:{{rowItemCount*250}}px;text-align:left;display:inline-block">{%endif%}<divclass="phone"><div>{{p.no}}</div><div><imgsrc="images/{{p.image}}"width="100"height="100"></div><p></p><div>{{p.mark}}</div><div>價格:¥<spanstyle="color:red">{{p.price}}</span></div><div>{{p.note}}</div></div>{%if(loop.index0+rowItemCount+1)isdivisibleby(rowItemCount)%}</div>{%endif%}{%endfor%}{%ifnumbersisnotdivisibleby(rowItemCount
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年綿陽市事業(yè)單位公開選調(diào)工作人員25人備考題庫有答案詳解
- 5G+急診急救的響應時效優(yōu)化策略
- 2025年庫爾勒公共停車場服務管理有限公司招聘備考題庫及1套完整答案詳解
- 3D打印技術在功能區(qū)腦腫瘤手術規(guī)劃中的創(chuàng)新
- 2025年浙江省經(jīng)濟建設投資有限公司招聘5人備考題庫及答案詳解參考
- 2025年長江財產(chǎn)保險股份有限公司總精算師及相關部門負責人招聘備考題庫及一套參考答案詳解
- 新疆醫(yī)科大學2025年高層次人才引進備考題庫及1套參考答案詳解
- 2025年成都市雙流區(qū)東升第一初級中學招聘教師備考題庫及參考答案詳解一套
- 2025年黃山太平經(jīng)濟開發(fā)區(qū)投資有限公司公開招聘高管人員備考題庫附答案詳解
- 2025年蘇州交投新基建科技有限公司公開招聘12名人員備考題庫及一套參考答案詳解
- 激光熔覆應用介紹
- 電除顫臨床操作規(guī)范指南樣本
- 教學《近似數(shù)》數(shù)學課件教案
- 2025年西昌市邛海瀘山風景名勝區(qū)管理局招聘5名執(zhí)法協(xié)勤人員備考題庫完整參考答案詳解
- 2025年中共湛江市委巡察服務保障中心、湛江市清風苑管理中心公開招聘事業(yè)編制工作人員8人備考題庫完整參考答案詳解
- 2025年產(chǎn)業(yè)融合發(fā)展與區(qū)域經(jīng)濟一體化進程研究可行性研究報告
- 2025呼倫貝爾莫旗消防救援大隊招聘消防文員(公共基礎知識)綜合能力測試題附答案解析
- 《國家賠償法》期末終結(jié)性考試(占總成績50%)-國開(ZJ)-參考資料
- 煙草證到期代辦委托書
- 128個護理診斷及措施
評論
0/150
提交評論