電子商務(wù)營銷模式有哪些長沙網(wǎng)站seo推廣公司
目錄
任務(wù)目標
創(chuàng)建Ajax網(wǎng)站
創(chuàng)建服務(wù)器程序
Selenium XX 等待
1. Selenium強制等待
2. Selenium隱性等待
3. Selenium循環(huán)等待
4.?Selenium顯示等待
等待方法
任務(wù)目標
- 在瀏覽器加載網(wǎng)頁的過程中,網(wǎng)頁的有些元素時常會有延遲的現(xiàn)象,在HTML元素還沒有準備好的情況下去操作這個HTML元素必然會出現(xiàn)錯誤,這個時候Selenium需要等待HTML元素。例如:上節(jié)實例中出現(xiàn)的select的下拉框元素,選項填充需要執(zhí)行JavaScript腳本。
- 我們來學(xué)習(xí)如果使用Selenium等待延遲的HTML元素并最終爬取元素的數(shù)據(jù)。
創(chuàng)建Ajax網(wǎng)站
phone.html?如下:
注:phone.html 文件要位于?templates?這個目錄下
<!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存儲函數(shù),每當 readyState 屬性改變時,就會觸發(fā)調(diào)用該函數(shù)。// readystate存有 XMLHttpRequest 的狀態(tài)。從 0 到 4 發(fā)生變化。// 0: 請求未初始化 1: 服務(wù)器連接已建立 2: 請求已接收 3: 請求處理中 4: 請求已完成,且響應(yīng)已就緒// status,200(OK),404(未找到頁面)if (http.readyState===4 && http.status===200){ //請求完成并且成功返回var xmark=document.getElementById("xmark"); var xcolor=document.getElementById("xcolor"); marks=eval("("+http.responseText+")");// JS中將JSON的字符串解析成JS對象格式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的對象格式轉(zhuǎn)化成str格式app.run()
模擬網(wǎng)站結(jié)果如下:
Selenium XX 等待
1. Selenium強制等待
必須等待的時間,缺點:不能準確把握需要等待的時間(有時操作還未完成,等待就結(jié)束了,導(dǎo)致報錯;有時操作已經(jīng)完成了,但等待時間還沒有到,浪費時間),如果在用例中大量使用,會浪費不必要的等待時間,影響測試用例的執(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è)置強制等待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隱性等待
該方法是瀏覽器對象調(diào)用的方法,即設(shè)置瀏覽器打開網(wǎng)頁均等待的時長, 同樣如果設(shè)置的隱性等待時間不夠長, 還是爬取不到需要的數(shù)據(jù)。
from selenium import webdriver
from selenium.webdriver.common.by import By
import timedriver = webdriver.Chrome()# 設(shè)置隱性加載時間1.5秒,即網(wǎ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ù)據(jù)的關(guān)鍵是<select>中是否已經(jīng)出現(xiàn)了<option>元素,我們可以設(shè)置一個循環(huán)來判斷是否有<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ù)據(jù)的關(guān)鍵是<select>中是否已經(jīng)出現(xiàn)了<option>元素,我們可以設(shè)置一個循環(huán)來判斷是否有<option>元素。 這個程序中使用 waitTime 變量來構(gòu)造一個循環(huán),它最長等待 10 秒,每間隔 0.5 秒就檢查一次<select>中是否有<option>存在,如果找到了<option>元素就退出等待循環(huán),不然就繼續(xù)等待直到<option>出現(xiàn)為止,如果 10 秒內(nè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)造一個定位元素的 locator 的對象,例如通過 XPath 的方法定位<select>中的<option>元素:
locator=(By.XPATH,"//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 秒就出現(xiàn)檢查一次。如果在 10 秒內(nèi)出現(xiàn)了該元素就是結(jié)束等待,否則就拋出一個異常,默認拋出異常為:NoSuchElementException。
這種等待的優(yōu)點:等待判斷準確,不會浪費多余的等待時間,在實際中使用可以提高執(zhí)行效率。
等待方法
1. EC.presence_of_element_located(locator)
這種形式是 等待 locator指定的元素 出現(xiàn) ,也就是HTML文檔中建立起了這個元素。
2. EC.visibility_of_element_located(locator)
這種形式是 等待 locator指定的元素 可見 ,注意元素出現(xiàn)時未見得可見,
例如:
<select id="xmark" style="display:none">...</select>
那么元素<select>是出現(xiàn)的但是不可見。
3. EC.element_to_be_clickable(locator)
這種形式是 等待 locator指定的元素 可以被點擊,
例如,在爬蟲程序中等待 <input type="submit"> 按鈕可用被點擊:
locator = (By.XPATH, "//input[@type='submit']")
WebDriverWait(driver, 10,0.5).until(EC.element_to_be_clickable(locator))
或者等待 <option> 是否可以被點擊: locator = (By.XPATH, "//select/option") WebDriverWait(driver,10,0.5).until(EC.element_to_be_clickable(locator))
使用這兩種方法都可以爬取到手機品牌數(shù)據(jù)。
但是注意使用: locator = (By.XPATH, "//select") WebDriverWait(driver,10,0.5).until(EC.element_to_be_clickable(locator))
是等待<select>是否可以點擊,這個元素就是沒有<option>時也是可以點擊的,因此用這個等待是爬取不到手機的品牌數(shù)據(jù)的。
4. EC.element_located_to_be_selected(locator)
這種形式是 等待 locator指定的元素 可以被選擇,可以被選擇的元素一般是<select>中的選項<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))
同樣能爬取到手機的品牌數(shù)據(jù)。
但是使用下列是不行的:
locator = (By.XPATH, "//input[@type='submit']")
WebDriverWait(driver, ? 10,0.5).until(EC.element_located_to_be_selected(locator))
因為這樣的 <input type='submit'> 是怎么樣也不可以選擇的。
5. EC.text_to_be_present_in_element(locator,text)
這種形式是等待 locator 指定的元素的文本中包含指定的text文本,例如爬蟲程序中使用下列的等待:
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è)置文本是"品牌",因此爬蟲程序可以爬取到手機品牌數(shù)據(jù)。
下一篇文章:實驗項目一:【文本反爬網(wǎng)站的分析和爬取】