转自:https://www.jianshu.com/p/a3b4839c6fb1
问题 一
如图:
![](http://upload-images.jianshu.io/upload_images/3971414-27a242d7f265cf15.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/516/format/webp)
其实这个问题我在网上试了几种方法,当时都没有解决,第二天上班再次尝试就好了(中间多了一步关机,开机),所以我也不知道到底是哪一个方法奏效了。
但是第一步先确认自己已经安装了 selenium:pip3 install selenium
如果还是报同样的错误,那就在脚本最头部加上下面这两句代码:
import sys
#print(sys.path)
sys.path.append('/usr/local/lib/python3.6/site-packages/')
代码里的路径是你的 Python 所在的路径。
问题二
如图:
![](http://upload-images.jianshu.io/upload_images/3971414-542be8678ea6e2f2.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/511/format/webp)
问题三
如图:
![](http://upload-images.jianshu.io/upload_images/3971414-a4e9d2a0663f673a.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/779/format/webp)
网上有一种方法最简便,但是很不友好,即使用一条命令安装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)。
简单书一下上面脚本用到的两个元素定位方法
-
右键单击选择“查看元素”,如下图:
查看元素 -
定位元素,如下图:
![](http://upload-images.jianshu.io/upload_images/3971414-8311519e96e04aa2.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1000/format/webp)
因为输入框元素有 id,所以我们使用 id 进行定位,图中高亮显示。再如点击按钮“百度一下”:
![](http://upload-images.jianshu.io/upload_images/3971414-37c4528295c3803b.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1000/format/webp)
问题五:
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 却没有出现,目前还未找到原因。看情况是因为没有准确定位到元素,但是如果没有定位到,为什么没有异常呢?
![](http://upload-images.jianshu.io/upload_images/3971414-18a655ef17a25db0.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/678/format/webp)
贴出脚本,希望有高人能帮助释疑:
#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()
验证码图片截屏如下:
![](http://upload-images.jianshu.io/upload_images/3971414-d3c316ab76bb9c94.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/81/format/webp)
该窗口的图片如下:
![](http://upload-images.jianshu.io/upload_images/3971414-35d5af86fb429d1a.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1000/format/webp)
问题十一: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()