Java自学者论坛

 找回密码
 立即注册

手机号码,快捷登录

恭喜Java自学者论坛(https://www.javazxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,会员资料板块,购买链接:点击进入购买VIP会员

JAVA高级面试进阶训练营视频教程

Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程Go语言视频零基础入门到精通Java架构师3期(课件+源码)
Java开发全终端实战租房项目视频教程SpringBoot2.X入门到高级使用教程大数据培训第六期全套视频教程深度学习(CNN RNN GAN)算法原理Java亿级流量电商系统视频教程
互联网架构师视频教程年薪50万Spark2.0从入门到精通年薪50万!人工智能学习路线教程年薪50万大数据入门到精通学习路线年薪50万机器学习入门到精通教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程MySQL入门到精通教程
查看: 700|回复: 0

Selenium +WebDiver 脚本执行问题记录解决

[复制链接]
  • TA的每日心情
    奋斗
    2024-11-24 15:47
  • 签到天数: 804 天

    [LV.10]以坛为家III

    2053

    主题

    2111

    帖子

    72万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    726782
    发表于 2021-7-3 10:40:42 | 显示全部楼层 |阅读模式

    转自:https://www.jianshu.com/p/a3b4839c6fb1

    问题 一

    如图:


     
    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 所在的路径。


    问题二

    如图:

     
    ImportError:cannot import name webdriver

    问题三

    如图:


     
    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)。

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

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


       
      查看元素
    • 定位元素,如下图:

     
    元素属性

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


     
    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()




    哎...今天够累的,签到来了1...
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|小黑屋|Java自学者论坛 ( 声明:本站文章及资料整理自互联网,用于Java自学者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2024-12-22 21:08 , Processed in 0.060342 second(s), 29 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

    快速回复 返回顶部 返回列表