用python-webdriver實(shí)現(xiàn)自動(dòng)填表的示例代碼
在日常工作中常常需要重復(fù)填寫(xiě)某些表單,如果人工完成,費(fèi)時(shí)費(fèi)力,而且網(wǎng)絡(luò)延遲令人十分崩潰。如果能夠用程序?qū)崿F(xiàn)自動(dòng)填表,效率可以提高一倍以上,并且能夠移植到多臺(tái)計(jì)算機(jī),進(jìn)一步提高工作效率。webdriver是python的selenium庫(kù)中的一個(gè)自動(dòng)化測(cè)試工具,它能完全模擬瀏覽器的操作,無(wú)需處理復(fù)雜的request、post,對(duì)爬蟲(chóng)初學(xué)者十分友好。
一、環(huán)境配置
python3.6+selenium庫(kù)+xlrd庫(kù)+xlwt庫(kù)
其中xlrd和xlwt庫(kù)用于讀寫(xiě)excel表中的數(shù)據(jù)。
還要下載一個(gè)瀏覽器的driver文件用于打開(kāi)瀏覽器,注意要選擇與計(jì)算機(jī)系統(tǒng)相符合的版本(max/windows64位/windows32位)
ChromeDriver:http://npm.taobao.org/mirrors/chromedriver/
IEDriver:http://selenium-release.storage.googleapis.com/index.html
將下載下來(lái)的driver.exe放到瀏覽器根目錄和python的根目錄
二、打開(kāi)網(wǎng)頁(yè)
以IE瀏覽器為例,以下兩行代碼就可以實(shí)現(xiàn)打開(kāi)一個(gè)IE瀏覽器并且訪問(wèn)我們需要填表的網(wǎng)站
driver= webdriver.Ie() driver.get('http://xxxx.com/')
如果網(wǎng)站需要登陸(需要填表的一般是公司內(nèi)部網(wǎng)站),再寫(xiě)一個(gè)login函數(shù),將driver作為參數(shù)調(diào)用
driver = login(driver)
注意一定要將driver傳回,這樣driver才能繼續(xù)接受程序的指令
三、元素定位
webdriver的工作原理是找到網(wǎng)頁(yè)中某一個(gè)元素,可以對(duì)其進(jìn)行填入數(shù)據(jù)或點(diǎn)擊等操作。
關(guān)于元素定位可以參考這篇博客
我主要用到的元素定位方式有
driver.find_element_by_id('someid')#通過(guò)元素的id定位 driver.find_element_by_css_selector("input[value='確定'")#查找一個(gè)input元素,它的value屬性值為'確定' driver.find_element_by_xpath("http://span[contains(@style,'COLOR: red')]/span[1]")#查找一個(gè)style屬性值為'COLOR:red'的span元素的第一個(gè)span子元素
(1)通過(guò)id定位
如果我們想在網(wǎng)頁(yè)表單的某一個(gè)位置填某項(xiàng)值或者點(diǎn)擊某個(gè)按鈕,我們首先要用開(kāi)發(fā)者工具查看這個(gè)元素的源代碼,然后首先觀察它有沒(méi)有id,如果有id,直接用id定位該元素。然后,用
driver.find_element_by_id('someid').click()#點(diǎn)擊元素 driver.find_element_by_id('someid').send_keys('somekeys')#填入'somekeys' driver.find_element_by_id('someid').clear()#清空輸入框中已有的值
實(shí)現(xiàn)我們想要做的操作。
(2)通過(guò)ccs selector定位
如果我們想要操作的元素沒(méi)有ID,那么我們就要找到它跟網(wǎng)頁(yè)其他元素不同的特征,ccs selector是一種十分靈活的定位方式,其中用value定位是一個(gè)不錯(cuò)的選擇。以
driver.find_element_by_css_selector("input[value='確定'")
為例,雙引號(hào)中的input可以換成任何網(wǎng)頁(yè)元素(div、span、input、a等),中括號(hào)中是該元素的某一個(gè)屬性(style、id、value、class等),等號(hào)后面是該屬性的值。
注意,如果網(wǎng)頁(yè)中有多個(gè)元素同時(shí)滿足ccs selector的條件,如有多個(gè)value=“確定” 的input,那么find_element_by_css_selector只會(huì)定位到在html源代碼中最靠前的一個(gè),而find_elements_by_css_selector會(huì)找到源代碼中所有滿足條件的元素,并以列表的形式返回這些找到的元素。例如,網(wǎng)頁(yè)中彈出很多個(gè)提示框,我們要一一去點(diǎn)確定,可以這樣操作
list=driver.find_elements_by_css_selector("input[value=' 確定 ']") for l in list: l.click()
但是,如果這些提示框是重疊出現(xiàn)的,而最上層的提示框?qū)嶋H上在源碼中更靠后的位置,那么列表中第一個(gè)“確定”元素就會(huì)被疊在上面的提示框遮擋,無(wú)法點(diǎn)擊,這個(gè)時(shí)候倒序一下數(shù)組就可以了,從最后一個(gè)“確定”元素開(kāi)始點(diǎn)擊
query=driver.find_elements_by_css_selector("input[value=' 確定 ']") for q in query[::-1]: q.click()
(3)通過(guò)xpath定位
xpath定位比較復(fù)雜但是非常全面,當(dāng)這個(gè)元素的class、style屬性和其他元素一樣,實(shí)在沒(méi)什么特點(diǎn)可以一步定位的時(shí)候,我們就可以用xpath,先找到我們想要的元素的父子兄弟元素,再定位到我們想要的元素。例如
driver.find_element_by_xpath('//*[@class="submit clear"]/input[1]').click() text =driver.find_element_by_xpath("http://input[@value=' 確定 ']/../preceding-sibling::div[1]").text driver.find_elements_by_xpath("http://span[contains(@style,'COLOR: red')]/span[1]")
引號(hào)中的//表示相對(duì)定位,表示從源代碼中任何地方開(kāi)始尋找。
//后可以跟任何元素,*代表任意元素,即定位符合屬性篩選任何元素。
中括號(hào)內(nèi)是屬性的篩選條件,@后可以加任意屬性。contains(@style,'COLOR: red')表示的篩選條件是:style屬性中包含”COLOR:red“。這里為什么不直接用@style='COLOR: red'
的原因是,可能在我們審查源代碼的時(shí)候這個(gè)元素的style屬性只有'COLOR: red'這一條,但是動(dòng)態(tài)界面的style屬性經(jīng)常變化,程序運(yùn)行時(shí)直接用等于是定位不到這個(gè)元素的。
我們通常需要靠先找到某個(gè)有id的元素,再通過(guò)層級(jí)關(guān)系定位到我們真正想要定位的元素,關(guān)于兄弟父子元素定位請(qǐng)參考http://www.dbjr.com.cn/article/92673.htm
/.. 可以定位這個(gè)元素的父親元素
/ 可以定位這個(gè)元素的子元素
/preceding-sibling:: 可以定位這個(gè)元素的哥哥元素
/following-sibling:: 可以定位這個(gè)元素的弟弟元素
如/input[1]表示子元素中第一個(gè)input、/../preceding-sibling::div[1]表示父元素的哥哥元素中的第一個(gè)div
(4)通過(guò)當(dāng)前節(jié)點(diǎn)定位
有時(shí)候我們會(huì)遇到需要判斷一下元素當(dāng)前的狀態(tài)(是否被選擇)再?zèng)Q定接下來(lái)的操作的情況,這時(shí)就需要用一個(gè)變量來(lái)保存當(dāng)前節(jié)點(diǎn)
LTE=driver.find_element_by_xpath("http://input[@id='LTE']/../span[1]"
然后再用get_attribute獲得當(dāng)前節(jié)點(diǎn)元素的屬性,在這個(gè)例子里,如果元素為藍(lán)色,就不需要點(diǎn)擊。代碼實(shí)現(xiàn)為:
if LTE.get_attribute("style")=="COLOR: blue": pass else: LET.click()
需要篩選出特定文本的情況:
red=driver.find_elements_by_xpath("http://span[contains(@style,'COLOR: red')]/span[1]")#找出所有紅色的文本 for r in red: if '低消' in r.text:#如果文本信息中包含‘低消' r.find_element_by_xpath("./../preceding-sibling::input[1]").click()#注意從當(dāng)前節(jié)點(diǎn)定位的時(shí)候要以‘./'開(kāi)頭 break
如果尋找的元素需要滾動(dòng)界面才能看到,這個(gè)時(shí)候可以用js聚焦此元素,頁(yè)面便會(huì)滾動(dòng)到該元素的位置
target=driver.find_element_by_css_selector("input[value=' 確定 ']") driver.execute_script("arguments[0].scrollIntoView();", target) target.click()
四、不確定情況處理
(1)有可能出現(xiàn)的彈窗
在填表過(guò)程中,有些地方有可能出現(xiàn)一個(gè)彈框也有可能不出現(xiàn),這個(gè)時(shí)候,無(wú)論這個(gè)彈窗是什么,用try..except語(yǔ)句處理就可以解決
js觸發(fā)的彈窗:
try: driver.find_element_by_css_selector("input[value=' 確定 ']").click() except Exception as e: pass
網(wǎng)頁(yè)alert彈窗:
try: driver.switch_to.alert.dismiss() except Exception: pass
dismiss()對(duì)應(yīng)的是alert彈窗的”取消“項(xiàng),accept()對(duì)應(yīng)的是”確定“項(xiàng),driver.switch_to.alert.text 可以獲得彈窗的文本內(nèi)容。
(2)數(shù)量不定的彈窗
對(duì)上文提到的多個(gè)提示框情況,除了用 query=driver.find_elements_by_css_selector("input[value=' 確定 ']") 一次性找到所有元素再順序或倒序點(diǎn)擊之外,還可以用一個(gè)while循環(huán)解決
while(1): try: driver.find_element_by_css_selector("input[value=' 確定 ']").click() except Exception as e: break
(3)網(wǎng)絡(luò)延遲
有些網(wǎng)頁(yè)在點(diǎn)擊查詢信息之后需要加載一段時(shí)間,加載中的頁(yè)面是找不到我們接下來(lái)想找的元素的,因此程序就會(huì)報(bào)錯(cuò),此時(shí)有兩種解決方法。
一種是固定等待一段時(shí)間,等待網(wǎng)頁(yè)加載完畢,這種方法的缺點(diǎn)是很難找到等待的最佳時(shí)間,太短的話頁(yè)面還沒(méi)加載完,太長(zhǎng)就影響效率
time.sleep(2)
另一種是用一個(gè)while循環(huán)一直尋找下一個(gè)我們要找的元素
while(1): try: driver.find_element_by_id('continueTrade').click() break except Exception: pass
這種方法的前提是下一個(gè)要找的元素必定會(huì)出現(xiàn)
五、frame處理
關(guān)于frame處理這篇博客寫(xiě)得非常好http://www.dbjr.com.cn/article/203425.htm
總結(jié)起來(lái)就是:frameset不用切,frame層層切。最好一系列填表操作完后都用 driver.switch_to.default_content() 回到原文檔,這樣不容易混亂
這里再補(bǔ)充一點(diǎn)frame沒(méi)有id時(shí)的切入方法
frame= self.driver.find_element_by_xpath("/html/body/div[12]/iframe")#先定位frame位置,用一個(gè)變量?jī)?chǔ)存這個(gè)節(jié)點(diǎn) self.driver.switch_to_frame(frame)#再切入這個(gè)節(jié)點(diǎn)
六、excel數(shù)據(jù)讀寫(xiě)
excel數(shù)據(jù)讀寫(xiě)十分簡(jiǎn)單,看代碼就好了:
def read(file): data = xlrd.open_workbook(file)#打開(kāi)excel文件 table = data.sheets()[0]#讀取第一個(gè)sheet的數(shù)據(jù) phones = table.col_values(0)#以列表形式存儲(chǔ)第一列數(shù)據(jù) peoples = table.col_values(1)#以列表形式存儲(chǔ)第二列數(shù)據(jù) return phones,peoples def write(result): file=xlwt.Workbook()#創(chuàng)建一個(gè)excel文件 table = file.add_sheet('sheet1')#添加一個(gè)sheet for i in range(len(result)):#寫(xiě)入數(shù)據(jù) table.write(i,0,result[i][0]) table.write(i,1,result[i][1]) table.write(i,2,result[i][2]) file.save('result.xls')
到此這篇關(guān)于用python-webdriver實(shí)現(xiàn)自動(dòng)填表的示例代碼的文章就介紹到這了,更多相關(guān)python webdriver 自動(dòng)填表內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- python+webdriver自動(dòng)化環(huán)境搭建步驟詳解
- selenium+python自動(dòng)化測(cè)試之使用webdriver操作瀏覽器的方法
- python使用webdriver爬取微信公眾號(hào)
- python實(shí)現(xiàn)圖書(shū)館搶座(自動(dòng)預(yù)約)功能的示例代碼
- python實(shí)現(xiàn)圖書(shū)館研習(xí)室自動(dòng)預(yù)約功能
- Python Requests模擬登錄實(shí)現(xiàn)圖書(shū)館座位自動(dòng)預(yù)約
- 使用Python webdriver圖書(shū)館搶座自動(dòng)預(yù)約的正確方法
相關(guān)文章
python中圖形庫(kù)turtle庫(kù)詳解(適用于計(jì)算機(jī)二級(jí))
Turtle庫(kù)是Python語(yǔ)言中的一個(gè)圖形庫(kù),可以用來(lái)繪制各種形狀,如線條、矩形、圓形等等,下面這篇文章主要給大家介紹了關(guān)于python中圖形庫(kù)turtle庫(kù)的相關(guān)資料,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下2024-08-08Python中subprocess模塊用法實(shí)例詳解
這篇文章主要介紹了Python中subprocess模塊用法,實(shí)例分析了subprocess模塊的相關(guān)使用技巧,需要的朋友可以參考下2015-05-05Python實(shí)現(xiàn)多任務(wù)進(jìn)程示例
大家好,本篇文章主要講的是Python實(shí)現(xiàn)多任務(wù)進(jìn)程示例,感興趣的同學(xué)趕快來(lái)看一看吧,對(duì)你有幫助的話記得收藏一下,方便下次瀏覽2022-01-01python用sqlacodegen根據(jù)已有數(shù)據(jù)庫(kù)(表)結(jié)構(gòu)生成對(duì)應(yīng)SQLAlchemy模型
本文介紹了如何使用sqlacodegen獲取數(shù)據(jù)庫(kù)所有表的模型類,然后使用ORM技術(shù)進(jìn)行CRUD操作,有此需求的朋友可以了解下本文2021-06-06Pytorch實(shí)戰(zhàn)之?dāng)?shù)據(jù)加載和處理詳解
Pytorch提供了許多工具來(lái)簡(jiǎn)化和希望數(shù)據(jù)加載,使代碼更具可讀性,本文將通過(guò)一些簡(jiǎn)單示例為大家具體講講,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2023-06-06Flask框架運(yùn)用Ajax實(shí)現(xiàn)數(shù)據(jù)交互的示例代碼
使用Ajax技術(shù)網(wǎng)頁(yè)應(yīng)用能夠快速地將增量更新呈現(xiàn)在用戶界面上,而不需要重載刷新整個(gè)頁(yè)面,這使得程序能夠更快地回應(yīng)用戶的操作,本文將簡(jiǎn)單介紹使用AJAX如何實(shí)現(xiàn)前后端數(shù)據(jù)通信2022-11-11