问题 一
如图:
其实这个问题我在网上试了几种方法,当时都没有解决,第二天上班再次尝试就好了(中间多了一步关机,开机),所以我也不知道到底是哪一个方法奏效了。
但是第一步先确认自己已经安装了 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()
问题十四