【python】用selenium webdriver做簡單的表格提交
selenium webdriver是一個自動化測試工具,相比於直接用get之類的方法能更為直觀的模擬使用者使用,但是,對我而言就是,額,挺好玩的,所以這一篇的側重點是一個接觸的過程,並沒有很系統的闡述這個工具。
註明:以下都以Chrome為例,IE可能在某些部分細節有所不同。
一、準備:1. Python 3.5 (所需安裝包(主要): selenium)
2.Chrome (所需外掛:ChromeDriver(以及記得新增環境變數PATH))
二、開始:
1.第一步都是import
from selenium import webdriver import time driver = webdriver.Chrome()
2.登入,如果不需要登入則可以跳過這一步:先通過右鍵檢視原始碼(關鍵段)
<label class="control-label" for="loginform-employee_no">管理帳號</label> <input type="text" id="loginform-employee_no" class="form-control" name="LoginForm[employee_no]"> <p class="help-block help-block-error"></p> </div> <div class="form-group field-loginform-password required"> <label class="control-label" for="loginform-password">密碼</label> <input type="password" id="loginform-password" class="form-control" name="LoginForm[password]">
接下來我們來了解下selenium的定位方法:
selenium的工作原理就是首先定位一個元素,然後再對其進行操作。Lucky,這段原始碼有id值,我們知道在html裡id都是唯一的。因此這裡我們找到的兩個ID:id="loginform-employee_no" id="loginform-password" 可以用elem_user = driver.find_element_by_id 這一方法來定位。
然後是操作部分:用keys類來模擬鍵盤輸入send(也可以是回車或者空格等等操作),先import Keys類:
綜合一下:from selenium.webdriver.common.keys import Keys
elem_user = driver.find_element_by_id("loginform-employee_no")
elem_user.send_keys("使用者名稱")
elem_pwd = driver.find_element_by_id("loginform-password")
elem_pwd.send_keys("密碼")
elem_pwd.send_keys(Keys.RETURN) #return和enter都是回車鍵,只是表達不同。
time.sleep(2) #sleep這一步跟網路環境有關,有時候如果輸入太快,可能會引起報錯。單位為秒。後面不再重複寫。
3.登入後就可以開始我們的填表了,直接開車(drive)到填表頁面(僅針對URL不變的填表地址,如果url是變動的需要另外處理這步driver.get):
driver.get("http://表單網址")
我們來看下這個需要填的內容:
等級: 這個內容是個下拉選單的型別:
看下原始碼:
<select id="employee-worker_level" class="form-control" name="Employee[worker_level]">
<option value="兼職">兼職</option>
<option value="見習">見習</option>
<option value="初級">初級</option>
<option value="中級">中級</option>
<option value="高階">高階</option>
</select>
好訊息是這個下拉選擇框有id,那麼我麼就可以像剛才那樣的定位,但是壞訊息是,這個下拉選擇框的選項沒有id,這時我們可以另一個定位方法,用tag name,find_elements_by_tag_name ,
這裡是 ”option“,並且是以類似list的方式存在的,所以引用標籤是0-4 代表著五個選項。所以這裡我們如果要選選項4的程式碼如下:
driver.find_element_by_id("employee-worker_level").find_elements_by_tag_name("option")[3].click()
這裡的click代表的是左鍵單擊。
工作角色:這個是個checkbox類的提交內容:
<div class="help-block"></div>
</div> <div class="form-group field-employee-worker_role">
<label class="control-label" for="employee-worker_role">工作角色</label>
<input type="hidden" name="Employee[worker_role]" value=""><div id="employee-worker_role"><label><input type="checkbox" name="Employee[worker_role][]" value="1"> 宣傳人員</label>
<label><input type="checkbox" name="Employee[worker_role][]" value="2"> 收費人員</label>
<label><input type="checkbox" name="Employee[worker_role][]" value="3"> 維護人員</label>
<label><input type="checkbox" name="Employee[worker_role][]" value="4"> 安裝人員</label>
<label><input type="checkbox" name="Employee[worker_role][]" value="5"> 移機人員</label>
<label><input type="checkbox" name="Employee[worker_role][]" value="9"> 綜合人員</label>
<label><input type="checkbox" name="Employee[worker_role][]" value="10"> 投訴專崗</label>
<label><input type="checkbox" name="Employee[worker_role][]" value="11"> 新開銷售</label></div>
<div class="hint-block">選擇人員的工作角色,如果非實際工作人員,請留空</div>
<div class="help-block"></div>
</div>
這裡也是類似的,我們看到有label這個tag name所以可以直接用label name,但是,如果我們需要複選的話,很簡單,用個迴圈就行了:
i=0
while (i<8) :
driver.find_element_by_id("employee-worker_role").find_elements_by_tag_name("label")[i].click()
i=i+1
(其實用for更簡單,但是我就是習慣用while)其他的需要填的內容就和登入裡需要的是類似的。
最後我們只需要用keys類回車一下,就可以提交表格了。
bonus:
好奇提交表格的時候能不能用click動作來完成,走向了作死之路:
我們先來看下提交的程式碼:
<div class="form-group">
<button type="submit" class="btn btn-success">新增</button> </div>
</form></div>
等等,id呢?name呢?讓我們看下其他的定位方法:
通過id定位元素:find_element_by_id("id_vaule")
通過name定位元素:find_element_by_name("name_vaule")
通過tag_name定位元素:find_element_by_tag_name("tag_name_vaule")
通過class_name定位元素:find_element_by_class_name("class_name")
通過css定位元素:find_element_by_css_selector();
通過xpath定位元素:find_element_by_xpath("xpath")
通過link定位:find_element_by_link_text("text_vaule")或者find_element_by_partial_link_text()
好的,貌似目前只能用Xpath的方法來定位了,讓我們來學習一下Xpath是什麼,這裡有一個教程:http://www.w3school.com.cn/xpath/index.asp 然後我們知道了,爸爸的爸爸是爺爺,各種類的定義,以及語法,接下來只要按教程簡單的寫出路徑……等等,為什麼都是div?難道只能一個個數了嗎?查詢後忽然發現,可以用瀏覽器比如chrome的檢查功能就可以知道Xpath:
複製之後,我們的程式碼就是:
driver.find_element_by_xpath('//*[@id="w0"]/div[11]/button').click() #記得注意單雙引號
報錯:
unknown error: Element <button type="submit" class="btn btn-success">...</button> is not clickable at point (57, 691). Other element would receive the click: <footer class="footer">...</footer>
(Session info: chrome=58.0.3029.110)
(Driver info: chromedriver=2.29.461591 (62ebf098771772160f391d75e589dc567915b233),platform=Windows NT 6.1.7601 SP1 x86_64)
查詢後原因是在當前頁面這個元素不可見,比如頁面只有300×300 但是元素定位在150×400,那麼對於這個對於瀏覽器來說就看不見了,當然人是知道還有下拉頁面的。(據說IE和FF是沒有這個問題的。)
那麼我們的思路就變成了,要如何下拉頁面:
1.藉助Java (具體大家戳參考4)
target = driver.find_element_by_id("id_keypair")
driver.execute_script("arguments[0].scrollIntoView();", target) #拖動到可見的元素去
2.利用鍵
用TAB鍵(或者向下鍵)
這裡我們測試一下向下鍵(找到最底下的元素,離提交最近的,再來一次TAB),最後再點選:
elem_user = driver.find_element_by_id("employee-move_time" )
elem_user.send_keys(Keys.TAB)
driver.find_element_by_xpath('//*[@id="w0"]/div[11]/button').click()
成功,撒花~
參考文章:
1.http://blog.csdn.net/jojoy_tester/article/details/53558402
2.http://www.cnblogs.com/lincj/p/3668215.html
3.http://www.w3school.com.cn/xpath/index.asp
4.http://www.cnblogs.com/landhu/p/5761794.html