Selenium+Python:下载文件(Firefox 和 Chrome)

摘要:
options=webdriver.ChromeOptions()prefs={'profile.default_content_settings.popups':0,'download.default_directory':os.getcwd()}options.add _ experial_optiondriver=webdriver.Chromedriver.getdriver.find_element_by_partial_link_Text。单击()已设置配置文件。Chrome浏览器content_settings的默认设置。0的弹出菜单将起作用。运行此代码时,不会弹出确认提示框,可以下载文件。因此,我在前面的代码之后添加了以下代码dialog=win32gui.FindWindow。如果该对话框已打印,则它具有一个值,表示已成功获取窗口句柄。

引自  https://blog.csdn.net/Momorrine/article/details/79794146

1.      环境

操作系统

Win10

IDE

Eclipse (Oxygen 4.7)+ PyDev 5.9.2 (JDK1.8)

Python

3.5

Selenium

selenium-3.9.0-py2.py3-none-any.whl

FirefoxDriver

0.20.0

Firefox浏览器

59.0.2(32位)

ChromeDriver

2.34

Chrome浏览器

63.0.3239.84

  

2.      Firefox

    这是虫师书里面的一个例子,我直接copy下来了

  1. from selenium import webdriver
  2.  
  3. fp = webdriver.FirefoxProfile()
  4. fp.set_preference("browser.download.folderList", 2)
  5. fp.set_preference("browser.download.manager.showWhenStarting", False) # 不起作用
  6. fp.set_preference("browser.download.dir", os.getcwd())
  7. fp.set_preference("browser.helperApps.neverAsk.saveToDisk", "application/octet-stream")
  8.  
  9. driver = webdriver.Firefox(firefox_profile=fp)
  10. driver.get("http://pypi.Python.org/pypi/selenium")
  11. driver.find_element_by_partial_link_text("selenium-3.11.0-py2.py3-none-any").click()

    但是很不幸,我这儿运行了,还是会弹出确认下载对话框,虽然设置了browser.download.manager.showWhenStarting为Flase,而由于Selenium无法操作该对话框,程序就卡在那儿了没能下载文件。

    我发现确认下载对话框,默认的焦点就在【确定】上,就试着在代码的最后添加这样一句:

ActionChains(driver).key_down(Keys.ENTER).perform()

当这个对话框出现的时候,手动键入ENTER是可以下载的,但这句代码并没有起作用,仍然没有下载文件。

3.      Chrome

    又试着增加了一些等待时间,始终没成功,就想着先换一个浏览器试试吧。

  1. options = webdriver.ChromeOptions()
  2. prefs = {'profile.default_content_settings.popups': 0, 'download.default_directory': os.getcwd()}
  3. options.add_experimental_option('prefs', prefs)
  4.  
  5. driver = webdriver.Chrome(chrome_options=options)
  6. driver.get("http://pypi.Python.org/pypi/selenium")driver.find_element_by_partial_link_text("selenium-3.11.0-py2.py3-none-any").click()

    对Chrome浏览器设置了profile.default_content_settings.popups为0是起作用的,运行这段代码,并没有弹出确认提示框,文件可以下载下来。

  

4.      Firefox+Pywin32

总觉得Firefox应该也会有办法来操作那个确认下载对话框,百度了一下,有提到Pywin32,可以获取并操作Windows窗口。那就先安装一个吧。 

    Pywin32,我是直接在命令行切换到Python根目录Scripts下,用pip install pywn32来安装的:

                          Selenium+Python:下载文件(Firefox 和 Chrome)第1张

     此外还用到一个可以获取Windows窗口属性的小工具Sky++,下载了解压缩就可以用了。运行Sky++后,点击【搜索】-【窗口搜索】菜单项打开【窗口搜索】对话框

                                            Selenium+Python:下载文件(Firefox 和 Chrome)第2张

按住其中的查找程序工具拖动到确认下载对话框后释放,【窗口搜索】对话框中会显示该窗口的句柄、标题、类等属性

                                              

                                            Selenium+Python:下载文件(Firefox 和 Chrome)第3张

通过后两个属性,就可以调用win32gui.FindWindow()获取该窗口的句柄,进而试着操作该窗口。注意 :虽然在Sky++中已经得到了句柄,但程序中不能直接用,因为每次运行窗口句柄是不同的。

     于是我在之前的代码后面增加了下面这句代码

dialog = win32gui.FindWindow("MozillaDialogClass", u"正在打开 selenium-3.11.0-py2.py3-none-any.whl")

打印了一下dialog,是有值的,就说明成功地获取到了窗口句柄了。 

    在获取到对话框的句柄后,就应该进一步获取【确定】按钮的句柄,然后点击该按钮,这样就应该可以下载文件了

  1. button = win32gui.FindWindowEx(dialog,None, "Button",None)
  2. win32gui.PostMessage(button, win32con.WM_LBUTTONDOWN, win32con.MK_LBUTTON, 0)
  3. win32gui.PostMessage(button, win32con.WM_LBUTTONUP, win32con.MK_LBUTTON, 0)

可是一直没成功,打印button一直是0,没有能获取到按钮的句柄,我怀疑是因为类名不正确的原因,但Sky++上无法看到按钮的信息,将类名换了又换,或许是"MozillaButtonClass",但始终没有获取。

    转而我又想,既然对话框获取到了,那对对话框键入ENTER呢,或许就可以了

win32gui.SendMessage(dialog,win32con.WM_KEYDOWN, win32con.VK_RETURN, 0)

嗯,真的可以了。因此用Firefox下载文件的完整代码是

  1. from selenium import webdriver
  2. import win32gui, win32con
  3.  
  4. fp = webdriver.FirefoxProfile()
  5. fp.set_preference("browser.download.folderList", 2)
  6. fp.set_preference("browser.download.dir", os.getcwd())
  7. fp.set_preference("browser.helperApps.neverAsk.saveToDisk", "application/octet-stream")
  8.  
  9. driver = webdriver.Firefox(firefox_profile=fp)
  10. driver.get("http://pypi.Python.org/pypi/selenium")
  11. driver.find_element_by_partial_link_text("selenium-3.11.0-py2.py3-none-any").click()
  12.  
  13. dialog = win32gui.FindWindow("MozillaDialogClass", u"正在打开 selenium-3.11.0-py2.py3-none-any.whl")
  14. win32gui.SendMessage(dialog,win32con.WM_KEYDOWN, win32con.VK_RETURN, 0)

    只是有一个问题,在import win32gui和win32con时,会有错误标识

Selenium+Python:下载文件(Firefox 和 Chrome)第4张Selenium+Python:下载文件(Firefox 和 Chrome)第5张

但运行没问题,不知道为什么。。。。。。 

    还要注意的是,需要根据当前网络的状况,以及下载文件的大小,适当添加一些等待时间,不然会可能出现最后关闭浏览器驱动时文件还没下完的情况。

5.      再次Firefox

    以上那些是昨天写的,是到昨天晚上为止的认识。今儿早上来了,在搜另外一个问题的时候,发现有博文说Firefox不能下载的原因,很可能是因为"browser.helperApps.neverAsk.saveToDisk"设置的文件类型不对的缘故,我把那个例子里面的类型"binary/octet-stream"贴过来试了一下,果然是可以的。但关于browser.download.manager.showWhenStarting设置为Flase不弹出提示框,其实代码中把文件类型设置正确了,没有设置browser.download.manager.showWhenStarting,也并没有弹出提示框。

  1. from selenium import webdriver
  2.  
  3. fp = webdriver.FirefoxProfile()
  4. fp.set_preference("browser.download.folderList", 2)
  5. fp.set_preference("browser.download.dir", os.getcwd())
  6. fp.set_preference("browser.helperApps.neverAsk.saveToDisk", "binary/octet-stream")
  7.  
  8. driver = webdriver.Firefox(firefox_profile=fp)
  9. driver.get("http://pypi.Python.org/pypi/selenium")
  10. driver.find_element_by_partial_link_text("selenium-3.11.0-py2.py3-none-any").click()
 

    有朋友友情提示,该加个参考资料小节。以前写东西的时候倒是每次都有注意引用这个问题,而最近写的也只是记录自己的一个学习Selenium+Python Web自动化测试的过程。不过好习惯还是该保持,这篇已经不太记得自己到底搜了哪些文章了,就记下几篇还记得的吧。

6.      参考资料

[1]  《Selenium2自动化测试实战:基于Python语言》虫师编著 电子工业出版社 2016年1月

[2] 用selenium的webdriver下载文件(基于python,firefox和chrome) https://blog.csdn.net/cyjs1988/article/details/74988997

[3]   Selenium 设置浏览器下载  http://www.cnblogs.com/fnng/p/7700620.html

免责声明:文章转载自《Selenium+Python:下载文件(Firefox 和 Chrome)》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇ASP.NET MVC+EF框架+EasyUI实现权限管理系列(10) VSS源代码管理GitHub远程文件删除下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

python修改镜像源

pip升级:python -m pip install --upgrade pip https://www.cnblogs.com/andy9468/p/10319442.html 1、在命令中临时修改 pip3 install -i https://pypi.tuna.tsinghua.edu.cn/simple pillow 2、永久修改镜像...

语音信号处理(声速,回声,音高,界面设计PyQt5)_Python语言

def YuSu(self): #语速设置 f = wave.open(r"test.wav", "rb") # 读取格式信息 # (nchannels, sampwidth, framerate, nframes, comptype, compname) params...

(python learn) 5 元组

首先我们要知道,字符串,元组,还有列表等数据类型在python中都属于序列数据类型。对这种数据类型,有一些统一的函数可用,比如: len() 可以返回长度 +可以连接两个序列 *可以重复两个序列中的元素 in可以判断某个元素是否在序列中 max()返回最大元素 min()返回最小元素 cmp()比较两个序列是否相等 下面,我们研究一下元组。 元组是一组被逗...

Python本地化例子

 关键字:Python 3.4,gettext,本地化,Localization OS:Windows 7,Mac 1. 创建一个locsample.py文件,文件内容如下,把所有需要本地化的字符串放到_()里面。# Python Localization Sample import os, gettext # Support localization...

[转载]iOS 开发中为什么更新UI都要放在主线程中?

原因有2个: 1、在子线程中是不能进行UI 更新的,而可以更新的结果只是一个幻像:因为子线程代码执行完毕了,又自动进入到了主线程,执行了子线程中的UI更新的函数栈,这中间的时间非常的短,就让大家误以为分线程可以更新UI。如果子线程一直在运行,则子线程中的UI更新的函数栈 主线程无法获知,即无法更新 2、只有极少数的UI能,因为开辟线程时会获取当前环境,如点...

python连接mysql的驱动

对于py2.7的朋友,直接可以用MySQLdb去连接,但是MySQLdb不支持python3.x。这是需要注意的~ 那应该用什么python连接mysql的驱动呢,在stackoverflow上有人解答: (1)可以尝试使用PyMySQL,但它很慢,最新的版本可以支持python 3.4. 地址:http://www.pymysql.org/ (2)还可以...