電子商務(wù)營(yíng)銷模式有哪些長(zhǎng)沙網(wǎng)站seo推廣公司
目錄
任務(wù)目標(biāo)
創(chuàng)建Ajax網(wǎng)站
創(chuàng)建服務(wù)器程序
Selenium XX 等待
1. Selenium強(qiáng)制等待
2. Selenium隱性等待
3. Selenium循環(huán)等待
4.?Selenium顯示等待
等待方法
任務(wù)目標(biāo)
- 在瀏覽器加載網(wǎng)頁(yè)的過(guò)程中,網(wǎng)頁(yè)的有些元素時(shí)常會(huì)有延遲的現(xiàn)象,在HTML元素還沒(méi)有準(zhǔn)備好的情況下去操作這個(gè)HTML元素必然會(huì)出現(xiàn)錯(cuò)誤,這個(gè)時(shí)候Selenium需要等待HTML元素。例如:上節(jié)實(shí)例中出現(xiàn)的select的下拉框元素,選項(xiàng)填充需要執(zhí)行JavaScript腳本。
- 我們來(lái)學(xué)習(xí)如果使用Selenium等待延遲的HTML元素并最終爬取元素的數(shù)據(jù)。
創(chuàng)建Ajax網(wǎng)站
phone.html?如下:
注:phone.html 文件要位于?templates?這個(gè)目錄下
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><form name="frm" action="/"><div><span id="msg"></span><label for="xmark"></label><select id="xmark"></select></div><input type="submit" value="提交" id="submit" disabled="true"></form>
</body>
<script>function loadMarks(){var http=new XMLHttpRequest(); http.open("get","/marks",true);http.send(null);http.onreadystatechange=function(){// onreadystatechange存儲(chǔ)函數(shù),每當(dāng) readyState 屬性改變時(shí),就會(huì)觸發(fā)調(diào)用該函數(shù)。// readystate存有 XMLHttpRequest 的狀態(tài)。從 0 到 4 發(fā)生變化。// 0: 請(qǐng)求未初始化 1: 服務(wù)器連接已建立 2: 請(qǐng)求已接收 3: 請(qǐng)求處理中 4: 請(qǐng)求已完成,且響應(yīng)已就緒// status,200(OK),404(未找到頁(yè)面)if (http.readyState===4 && http.status===200){ //請(qǐng)求完成并且成功返回var xmark=document.getElementById("xmark"); var xcolor=document.getElementById("xcolor"); marks=eval("("+http.responseText+")");// JS中將JSON的字符串解析成JS對(duì)象格式for(var i=0;i<marks.length;i++) xmark.options.add(new Option(marks[i],marks[i])); document.getElementById("submit").disabled=false;document.getElementById("msg").innerHTML="品牌";}};}loadMarks();
</script>
</html>
創(chuàng)建服務(wù)器程序
服務(wù)器server.py程序如下:
import flask
import json
import timeapp = flask.Flask(__name__)@app.route("/")
def index():return flask.render_template("phone.html")@app.route("/marks")
def loadMarks():time.sleep(1)marks = ["華為", "蘋果", "三星"]return json.dumps(marks) # 將JSON的對(duì)象格式轉(zhuǎn)化成str格式app.run()
模擬網(wǎng)站結(jié)果如下:
Selenium XX 等待
1. Selenium強(qiáng)制等待
必須等待的時(shí)間,缺點(diǎn):不能準(zhǔn)確把握需要等待的時(shí)間(有時(shí)操作還未完成,等待就結(jié)束了,導(dǎo)致報(bào)錯(cuò);有時(shí)操作已經(jīng)完成了,但等待時(shí)間還沒(méi)有到,浪費(fèi)時(shí)間),如果在用例中大量使用,會(huì)浪費(fèi)不必要的等待時(shí)間,影響測(cè)試用例的執(zhí)行效率。
from selenium import webdriver
from selenium.webdriver.common.by import By
import timedriver = webdriver.Chrome()
driver.get("http://127.0.0.1:5000")# 設(shè)置強(qiáng)制等待1.5秒,
time.sleep(1.5)marks = driver.find_elements(By.XPATH, "//select/option")
print("品牌數(shù)量:", len(marks))
for mark in marks:print(mark.text)
form = driver.find_element(By.XPATH, "//form")
print(form.get_attribute("innerHTML").strip())
time.sleep(5)
driver.close()
2. Selenium隱性等待
該方法是瀏覽器對(duì)象調(diào)用的方法,即設(shè)置瀏覽器打開(kāi)網(wǎng)頁(yè)均等待的時(shí)長(zhǎng), 同樣如果設(shè)置的隱性等待時(shí)間不夠長(zhǎng), 還是爬取不到需要的數(shù)據(jù)。
from selenium import webdriver
from selenium.webdriver.common.by import By
import timedriver = webdriver.Chrome()# 設(shè)置隱性加載時(shí)間1.5秒,即網(wǎng)頁(yè)在加載時(shí)最長(zhǎng)等待 seconds 秒
driver.implicitly_wait(1.5)driver.get("http://127.0.0.1:5000")
marks = driver.find_elements(By.XPATH, "//select/option")
print("品牌數(shù)量:", len(marks))
for mark in marks:print(mark.text)
form = driver.find_element(By.XPATH, "//form")
print(form.get_attribute("innerHTML").strip())
time.sleep(5)
driver.close()
3. Selenium循環(huán)等待
循環(huán)等待 實(shí)際上這個(gè)爬蟲(chóng)程序能否爬到數(shù)據(jù)的關(guān)鍵是<select>中是否已經(jīng)出現(xiàn)了<option>元素,我們可以設(shè)置一個(gè)循環(huán)來(lái)判斷是否有<option>元素
from selenium import webdriver
from selenium.webdriver.common.by import By
import timedriver = webdriver.Chrome()
try:driver.get("http://127.0.0.1:5000")waitTime = 0while waitTime < 10:marks = driver.find_elements(By.XPATH, "//select/option")if len(marks) > 0:breaktime.sleep(0.5)waitTime += 0.5if waitTime >= 10:raise Exception("Waiting time out")marks = driver.find_elements(By.XPATH, "//select/option")print("品牌數(shù)量:", len(marks))for mark in marks:print(mark.text)form = driver.find_element(By.XPATH, "//form")print(form.get_attribute("innerHTML").strip())
except Exception as err:print(err)
time.sleep(5)
driver.close()
循環(huán)等待 實(shí)際上這個(gè)爬蟲(chóng)程序能否爬到數(shù)據(jù)的關(guān)鍵是<select>中是否已經(jīng)出現(xiàn)了<option>元素,我們可以設(shè)置一個(gè)循環(huán)來(lái)判斷是否有<option>元素。 這個(gè)程序中使用 waitTime 變量來(lái)構(gòu)造一個(gè)循環(huán),它最長(zhǎng)等待 10 秒,每間隔 0.5 秒就檢查一次<select>中是否有<option>存在,如果找到了<option>元素就退出等待循環(huán),不然就繼續(xù)等待直到<option>出現(xiàn)為止,如果 10 秒內(nèi)還沒(méi)有出現(xiàn)據(jù)拋出異常。
4.?Selenium顯示等待
from selenium import webdriver
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import Bydriver = webdriver.Chrome()
try:driver.get("http://127.0.0.1:5000")# 顯示等待locator = (By.XPATH, "//select/option")WebDriverWait(driver, 10, 0.5).until(EC.presence_of_element_located(locator))marks = driver.find_elements(By.XPATH, "//select/option")print("品牌數(shù)量:", len(marks))for mark in marks:print(mark.text)form = driver.find_element(By.XPATH, "//form")print(form.get_attribute("innerHTML").strip())
except Exception as err:print(err)
構(gòu)造一個(gè)定位元素的 locator 的對(duì)象,例如通過(guò) XPath 的方法定位<select>中的<option>元素:
locator=(By.XPATH,"//select/option")
使用 WebDriverWait 構(gòu)造一個(gè)實(shí)例,調(diào)用 until 方法:
WebDriverWait(driver, 10,0.5).until(EC.presence_of_element_located(locator))
這條語(yǔ)句的含義是等待 locator 指定的元素出現(xiàn),最長(zhǎng)等待 10 秒,每間隔 0.5 秒就出現(xiàn)檢查一次。如果在 10 秒內(nèi)出現(xiàn)了該元素就是結(jié)束等待,否則就拋出一個(gè)異常,默認(rèn)拋出異常為:NoSuchElementException。
這種等待的優(yōu)點(diǎn):等待判斷準(zhǔn)確,不會(huì)浪費(fèi)多余的等待時(shí)間,在實(shí)際中使用可以提高執(zhí)行效率。
等待方法
1. EC.presence_of_element_located(locator)
這種形式是 等待 locator指定的元素 出現(xiàn) ,也就是HTML文檔中建立起了這個(gè)元素。
2. EC.visibility_of_element_located(locator)
這種形式是 等待 locator指定的元素 可見(jiàn) ,注意元素出現(xiàn)時(shí)未見(jiàn)得可見(jiàn),
例如:
<select id="xmark" style="display:none">...</select>
那么元素<select>是出現(xiàn)的但是不可見(jiàn)。
3. EC.element_to_be_clickable(locator)
這種形式是 等待 locator指定的元素 可以被點(diǎn)擊,
例如,在爬蟲(chóng)程序中等待 <input type="submit"> 按鈕可用被點(diǎn)擊:
locator = (By.XPATH, "//input[@type='submit']")
WebDriverWait(driver, 10,0.5).until(EC.element_to_be_clickable(locator))
或者等待 <option> 是否可以被點(diǎn)擊: locator = (By.XPATH, "//select/option") WebDriverWait(driver,10,0.5).until(EC.element_to_be_clickable(locator))
使用這兩種方法都可以爬取到手機(jī)品牌數(shù)據(jù)。
但是注意使用: locator = (By.XPATH, "//select") WebDriverWait(driver,10,0.5).until(EC.element_to_be_clickable(locator))
是等待<select>是否可以點(diǎn)擊,這個(gè)元素就是沒(méi)有<option>時(shí)也是可以點(diǎn)擊的,因此用這個(gè)等待是爬取不到手機(jī)的品牌數(shù)據(jù)的。
4. EC.element_located_to_be_selected(locator)
這種形式是 等待 locator指定的元素 可以被選擇,可以被選擇的元素一般是<select>中的選項(xiàng)<option>、輸入的多選框 <input type="checkbox"> 以及輸入的單選框 <input type="radio">等元素。
locator = (By.XPATH, "//select/option")
WebDriverWait(driver, 10,0.5).until(EC.element_located_to_be_selected(locator))
同樣能爬取到手機(jī)的品牌數(shù)據(jù)。
但是使用下列是不行的:
locator = (By.XPATH, "//input[@type='submit']")
WebDriverWait(driver, ? 10,0.5).until(EC.element_located_to_be_selected(locator))
因?yàn)檫@樣的 <input type='submit'> 是怎么樣也不可以選擇的。
5. EC.text_to_be_present_in_element(locator,text)
這種形式是等待 locator 指定的元素的文本中包含指定的text文本,例如爬蟲(chóng)程序中使用下列的等待:
locator = (By.ID, "msg")
WebDriverWait(driver, 10,0.5).until(EC.text_to_be_present_in_element(locator,"品"))
即等待<span id="msg">......</span>元素中的文本包含"品"字,由于在<option>出現(xiàn)后設(shè)置文本是"品牌",因此爬蟲(chóng)程序可以爬取到手機(jī)品牌數(shù)據(jù)。
下一篇文章:實(shí)驗(yàn)項(xiàng)目一:【文本反爬網(wǎng)站的分析和爬取】