本文由博主(SunboyL)原創,轉載請注明出處:https://www.cnblogs.com/SunboyL/p/11563345.html
因為工作原因,需要將xls文件的數據錄入到網上。因為數據量太多,而且以后時不時還需要用上,Ctrl+C,Ctrl+V不是長久之計。所以萌生一個想法,寫一個工具,用於把xls文件的數據錄入到網站上。
筆者這段時間才剛剛開始了解HTML、JavaScript,很多東西都是剛剛初步有點認識。寫的比較詳細,如果你跟我一樣,相信文章對你很有用。如果是老鳥,那就跳過吧~
讀寫xls部分省略。
要實現填寫表單,需要:
1.python的selenium庫。系統了解selenium,請到:http://www.testclass.net/selenium_python
2.Chrome瀏覽器,也可以使用其他瀏覽器,參考:http://www.testclass.net/selenium_python/selenium3-browser-driver
3.與谷歌瀏覽器版本對應的chromedriver,下載地址:https://sites.google.com/a/chromium.org/chromedriver/home,打不開就用taobao備用地址:http://npm.taobao.org/mirrors/chromedriver/
一、配置chromedriver
1)先查看自身Chrome瀏覽器的版本號,再到chromedriver下載網站找到與自身Chrome瀏覽器匹配的chromedriver版本下載使用。筆者下載的是win32版本,詳細步驟如圖:
2)下載后解壓,並把chromedriver.exe拷貝到Chrome瀏覽器所在目錄,詳細步驟如圖所示:
3)為了方便,我們也可以把Chrome路徑添加到系統環境變量中:
到此,chromedriver就配置完畢啦。
二、Python安裝selenium庫
使用如下命令即可完成安裝:
pip3 install selenium
如圖:
三、測試selenium庫使用
編輯如下代碼,實現打開百度頁面並搜索“cnblogs”的簡單功能(后續講解代碼中id的來源):
import os from selenium import webdriver def test(): driver = webdriver.Chrome("chromedriver.exe") # chromedriver所在路徑 driver.get(r"http://www.baidu.com") driver.find_element_by_id("kw").send_keys("cnblogs") # 輸入cnblogs driver.find_element_by_id("su").click() # 點擊“百度一下”搜索 if __name__ == "__main__": test() os.system("pause")
測試完成,接下來就可以使用了。
四、selenium的使用
selenium提供了多種定位網頁元素的方法,如通過id、name、classname、xpath等多種方式。詳細請參考:http://www.testclass.net/selenium_python/find-element/,這里就不一一贅述了。
到此,我們就已經幾乎做好填寫表單的所有准備啦,最后一步,就是定位我們的目標網站的具體元素並實現填表了。
五、定位網頁元素
chrome開發者工具為我們提供了非常遍歷的方式定位網頁元素。我們以定位百度首頁的文本輸入框以及“百度一下”按鈕為例:
1、打開Chrome瀏覽器,按F12打開開發者工具。點擊進入“Elements”板塊,我們就能看到網頁完整的HTML代碼。如圖:
2.點擊開發者工具左上角的小按鈕來定位頁面元素,我們定位文本輸入框找到輸入框對應的元素id,當然,我們也可以通過其他值來定位,如圖:
接下來我們定位百度按鈕:
從這里我們看到,文本輸入框的id是“kw”,百度一下按鈕的id是su,有了如上信息,我們就可以寫出第三大點的代碼了。
六、實踐中遇到的一些問題:處理批量填表時拋出異常:selenium.common.exceptions.ElementClickInterceptedException: Message: element click intercepted
對於批量數據的填寫,常常需要我們點擊按鈕增加填寫區域。如下圖示例
通過Chrome開發者工具,我們定位到該按鈕元素,三個按鈕屬於同一個類,class=“addbutton”:
假設我們已經定位到改行元素row_element,接下來我們就開始實現代碼吧:
1)第一版代碼
我們通過row_element定位到第二個addbutton按鈕並點擊,代碼如下:
通過以上方式,我們實現了自動添加一行填表區域的邏輯。
但是事與願違,當我用這種方式批量填表時,填表途中拋出了異常:
selenium.common.exceptions.ElementClickInterceptedException: Message: element click intercepted: Element <input type="button" tabindex="-1" class="addbutton" value="+↓" onclick="postInsert(11)"> is not clickable at point (737, 833). Other element would receive the click: <iframe frameborder="0" name="hiddenwin" id="hiddenwin" class="debugwin"></iframe>
(Session info: chrome=77.0.3865.90)
大概意思就是被其他元素攔截了。只能再找新的辦法。
各種查資料,結果就出現了第二版代碼。
2)第二版代碼
將第一版代碼稍作修改,使用JavaScript腳本執行,如圖:

print("添加一條填表區...") add_buttons = row_element.find_elements_by_class_name('addbutton') # add_buttons[1].click() driver.execute_script("arguments[0].click()", add_buttons[1])
經過修改,再也沒有出現剛剛的報錯了~
3)第三版代碼,進一步改進
隨着自己對JavaScript和HTLM的進一步熟悉,重新看了一下發現自己繞了個大彎,其實完全有更簡單的方法實現。
筆者原本的邏輯,是通過各種方式定位到了該行元素,再定位到具體按鈕,進而使用click()實現。
但是我們回頭看一下HTLM源碼,如下:
我們可以看到,其實click事件就是響應了一個postInsert()函數!
我們直接使用driver.execute_script()調用postInsert()函數就可以了,完全不需要定位元素位置呀,不!需要!定位!呀!呀!
postInsert()函數接受一個整型值,代表在第幾行的后面插入新行。對代碼稍作修改,就有了第三版代碼,一行就搞定了:
至此,工具就寫完了,筆者這幾天是從0基礎了解HTML、JavaScript開始,一步一步加深認識,並把工具寫好,碰到的坑,數不盡數。但是收獲也很大,繼續加油吧!