轉自:https://www.jianshu.com/p/a3b4839c6fb1
問題 一
如圖:

其實這個問題我在網上試了幾種方法,當時都沒有解決,第二天上班再次嘗試就好了(中間多了一步關機,開機),所以我也不知道到底是哪一個方法奏效了。
但是第一步先確認自己已經安裝了 selenium:
pip3 install selenium
如果還是報同樣的錯誤,那就在腳本最頭部加上下面這兩句代碼:
import sys #print(sys.path) sys.path.append('/usr/local/lib/python3.6/site-packages/')
代碼里的路徑是你的 Python 所在的路徑。
問題二
如圖:

問題三
如圖:

網上有一種方法最簡便,但是很不友好,即使用一條命令安裝geckodriver:
brew install geckodriver
以上方法基本可以放棄(因為我抗拒使用鏡像)。
還有一個方法,稍微麻煩一些,即自己下載geckodriver文件。
下載鏈接:https://github.com/mozilla/geckodriver/releases。下載適合自己的安裝包,解壓后將geckodriverckod 存放至 /usr/local/bin/ 路徑下即可(mac 本)。
Windows系統方法:
-
下載解壓后將getckodriver.exe復制到Firefox的安裝目錄下,如(C:\Program Files\Mozilla Firefox),並在環境變量Path中添加路徑:C:\Program Files\Mozilla Firefox;
-
重啟cmd或IDLE再次運行代碼即可
問題四:
Message: Process unexpectedly closed with status 0
報這個錯誤是因為需要啟動的瀏覽器 crashed。重啟瀏覽器就好了。
我只是簡簡單單的寫了一個簡簡單單的腳本,竟然遇到了這么多問題,心塞的很吶。腳本真的很簡單:
# coding=utf-8 #!/usr/bin/env python3 import sys #print(sys.path) sys.path.append('/usr/local/lib/python3.6/site-packages/') from selenium import webdriver import time browser = webdriver.Firefox() time.sleep(5) browser.get("http://www.baidu.com") print browser.title browser.find_element_by_id("kw").send_keys("selenium") browser.find_element_by_id("su").click() time.sleep(5) #刷新當前頁面 browser.refresh() time.sleep(3) browser.quit()
我的腳本是在Sublime Text 編輯器上進行變寫的,也可以在編輯器上執行腳本(command+B)。
簡單書一下上面腳本用到的兩個元素定位方法
-
右鍵單擊選擇“查看元素”,如下圖:
查看元素 -
定位元素,如下圖:

因為輸入框元素有 id,所以我們使用 id 進行定位,圖中高亮顯示。再如點擊按鈕“百度一下”:

問題五:
UnicodeDecodeError: 'utf8' codec can't decode byte 0xe7 in position 0: unexpected end of data
當我嘗試使用 CSS 進行定位輸入框並輸入漢字文本內容的時候出現了上述錯誤,看錯誤類型應該是編碼問題,腳本如下:
browser.find_element_by_css_selector("form.fm span.bg.s_ipt_wr.quickdelete-wrap input.s_ipt").send_keys("簡書")
解決辦法,在漢字前加字母 u 即可解決,腳本如下:
browser.find_element_by_css_selector("form.fm span.bg.s_ipt_wr.quickdelete-wrap input.s_ipt").send_keys(u"簡書")
問題六:
selenium.common.exceptions.ElementNotVisibleException: Message: element not visible
我嘗試了各種定位元素的方法都是報這樣一個錯誤,元素雖然存在,但是不可見,所以無法對其進行click()或者send_keys()操作。比如以下方法均不行:
driver.find_element_by_name('password').send_keys('password') driver.find_element_by_css_selector("input[type=password]").send_keys("123456") driver.find_element_by_xpath("//input[@type='password']").send_keys("123456")
但是在我放棄以后,在解決其他問題的時候無意間嘗試了這個方法,竟然成功了,定位方法如下:
ActionChains(driver).click(driver.find_element(By.ID,'TANGRAM__PSP_3__password')).send_keys("1234567").perform()
問題七:
selenium.common.exceptions.TimeoutException: Message:
這個異常報錯的代碼因為使用了WebDriverWait類,如下:
element = WebDriverWait(driver,10).until( EC.element_to_be_clickable((By.XPATH,"(//input[@type='password')"))) element.click().send_keys("1234567")
這個定位方法是我在嘗試解決問題六的時候使用的,但是還是無法定位成功,解決辦法是使用問題六的辦法:
ActionChains(driver).click(driver.find_element(By.ID,'TANGRAM__PSP_3__password')).send_keys("1234567").perform()
問題八:
selenium.common.exceptions.WebDriverException: Message: TypeError: rect is undefined
這個問題我也沒有解決,采取了一個投機取巧的辦法。使用 Fifefox 瀏覽器時報錯,換了 Chrome瀏覽器,正常。在 stackoverflow 上有一種說法是因為 Firefox 版本的問題。但是我更新的最新版本問題依然存在。
問題九:
selenium.common.exceptions.NoAlertPresentException: Message: no alert open
應該是定位到一個元素,點擊以后彈出一個 alert(如下圖),定位的時候總是報錯,無法准確定位,最后改用步驟六的定位方法,不再報錯,但是想要的 alert 卻沒有出現,目前還未找到原因。看情況是因為沒有准確定位到元素,但是如果沒有定位到,為什么沒有異常呢?

貼出腳本,希望有高人能幫助釋疑:
#coding=utf-8 import sys sys.path.append("/usr/local/lib/python3.6/site-packages/") from selenium import webdriver from selenium.webdriver.common.action_chains import ActionChains from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.common.by import By import time #driver = webdriver.Firefox() driver = webdriver.Chrome('./chromedriver') driver.implicitly_wait(10) driver.get("http://www.baidu.com") #鼠標懸停至“設置”鏈接 link = driver.find_element_by_link_text('設置') ActionChains(driver).move_to_element(link).perform() #打開“搜索”設置 driver.find_element_by_link_text("搜索設置").click() #保存設置 #driver.find_element_by_class_name("prefpanelgo").click() #driver.find_element_by_xpath("//a[@class='prefpanelgo']").click() ActionChains(driver).click(driver.find_element(By.CLASS_NAME,'prefpanelgo')).perform() #texts = driver.switch_to_alert().text #print("警告的內容是%s"%texts) time.sleep(10) driver.implicitly_wait(10) #接受警告框 driver.switch_to_alert().accept() time.sleep(5) driver.quit()
問題十:ImportError: cannot import name _imaging
這個問題在獲取屏幕截圖識別驗證碼的時候出現,折騰了一天各種辦法都嘗試了依然沒能解決。一直都在使用 Sublime Text 進行代碼編寫,也不知道哪里操作不當打開了 PyCharm,好久沒有這個了,心想就用一下吧,沒想到問題竟然沒有了。代碼如下:
#coding=utf-8 import sys sys.path.append("/usr/local/lib/python3.6/site-packages/") from selenium import webdriver from PIL import Image,ImageEnhance import time driver = webdriver.Chrome('./chromedriver') driver.implicitly_wait(10) driver.get("http://192.168.11.5:3004/#/login") #登錄 driver.find_element_by_class_name("el-input__inner").send_keys("dmin") driver.find_element_by_xpath("//input[@type='password']").send_keys("123456") driver.save_screenshot('/Users/guxuecheng/Desktop/screenshot.png') #瀏覽器頁面截屏 driver.get_screenshot_as_file('/Users/guxuecheng/Desktop/screenImg.png') #定位驗證碼位置及大小 location = driver.find_element_by_class_name('captcha').location size = driver.find_element_by_class_name('captcha').size left = location['x'] top = location['y'] right = location['x'] + size['width'] bottom = location['y'] + size['height'] #從文件讀取截圖,截取驗證碼位置再次保存 img = Image.open('/Users/guxuecheng/Desktop/screenImg.png').crop((left,top,right,bottom)) img = img.convert('L') #轉換模式:L | RGB img = ImageEnhance.Contrast(img)#增強對比度 img = img.enhance(2.0) #增加飽和度 img.save('/Users/guxuecheng/Desktop/screenImg.png') time.sleep(10) driver.quit()
驗證碼圖片截屏如下:

該窗口的圖片如下:

問題十一:ModuleNotFoundError: No module named 'pytesseract'
解決辦法:
pip install pytesseract
問題十二:pytesseract.pytesseract.TesseractNotFoundError: tesseract is not installed or it's not in your path
解決辦法:
brew install tesseract
問題十和問題十一都是在識別驗證碼的時候引用一個 module 導致的,不過好在最后也勉強算是成功,很遺憾使用這種方法進行驗證碼識別,准確率很低,有時候甚至什么都識別不出來,代碼如下:
#coding=utf-8 import sys sys.path.append("/usr/local/lib/python3.6/site-packages/") from selenium import webdriver from PIL import Image,ImageEnhance import pytesseract import time driver = webdriver.Chrome('./chromedriver') #driver = webdriver.Chrome() driver.implicitly_wait(10) driver.get("http://192.168.11.5:3004/#/login") #登錄 driver.find_element_by_class_name("el-input__inner").send_keys("admin") driver.find_element_by_xpath("//input[@type='password']").send_keys("123456") driver.save_screenshot('/Users/guxuecheng/Desktop/screenshot.png') #瀏覽器頁面截屏 driver.get_screenshot_as_file('/Users/guxuecheng/Desktop/screenImg.png') #定位驗證碼位置及大小 location = driver.find_element_by_class_name('captcha').location size = driver.find_element_by_class_name('captcha').size left = location['x'] top = location['y'] right = location['x'] + size['width'] bottom = location['y'] + size['height'] #從文件讀取截圖,截取驗證碼位置再次保存 img = Image.open('/Users/guxuecheng/Desktop/screenImg.png').crop((left,top,right,bottom)) img = img.convert('L') #轉換模式:L | RGB img = ImageEnhance.Contrast(img)#增強對比度 img = img.enhance(2.0) #增加飽和度 img.save('/Users/guxuecheng/Desktop/screenImg.png') #讀取識別驗證碼 yanzhengma = Image.open('/Users/guxuecheng/Desktop/screenImg.png') #text = pytesseract.image_to_string(yanzhengma).strip() text = pytesseract.image_to_string(yanzhengma) print('驗證碼是:%s'%text.strip()) driver.find_element_by_xpath('/html/body/div/div[2]/div[2]/form/div[3]/div/div/div[1]/div/input').send_keys(text.strip()) time.sleep(10) #driver.quit()
問題十三:selenium.common.exceptions.InvalidSelectorException: Message: invalid selector: Compound class names not permitted
這個錯誤出現在定位一個登錄按鈕的時候報出,看意思是定位方法無效,這個元素的 class_name是一個復合 name。
所以換了一個定位方法:
driver.find_element_by_xpath("//button[@type = 'button']").click()