Selenium WebDiver 脚本执行问题记录

问题 一

如图:

《Selenium WebDiver 脚本执行问题记录》 ImportError:No module named selenium

其实这个问题我在网上试了几种方法,当时都没有解决,第二天上班再次尝试就好了(中间多了一步关机,开机),所以我也不知道到底是哪一个方法奏效了。
但是第一步先确认自己已经安装了 selenium:
pip3 install selenium
如果还是报同样的错误,那就在脚本最头部加上下面这两句代码:

import sys
#print(sys.path)
sys.path.append('/usr/local/lib/python3.6/site-packages/')

代码里的路径是你的 Python 所在的路径。

问题二

如图:

《Selenium WebDiver 脚本执行问题记录》 ImportError:cannot import name webdriver

问题三

如图:

《Selenium WebDiver 脚本执行问题记录》 Message: ‘geckodriver’ executable needs to be in PATH.

网上有一种方法最简便,但是很不友好,即使用一条命令安装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)。

简单书一下上面脚本用到的两个元素定位方法

  • 右键单击选择“查看元素”,如下图:

    《Selenium WebDiver 脚本执行问题记录》 查看元素

  • 定位元素,如下图:

《Selenium WebDiver 脚本执行问题记录》 元素属性

因为输入框元素有 id,所以我们使用 id 进行定位,图中高亮显示。再如点击按钮“百度一下”:

《Selenium WebDiver 脚本执行问题记录》 元素属性

问题五:

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 却没有出现,目前还未找到原因。看情况是因为没有准确定位到元素,但是如果没有定位到,为什么没有异常呢?

《Selenium WebDiver 脚本执行问题记录》 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()

验证码图片截屏如下:

《Selenium WebDiver 脚本执行问题记录》 精准截取验证码图片

该窗口的图片如下:

《Selenium WebDiver 脚本执行问题记录》 截取窗口图片

问题十一: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()

问题十四

    原文作者:顾顾314
    原文地址: https://www.jianshu.com/p/a3b4839c6fb1
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞