全部版块 我的主页
论坛 数据科学与人工智能 数据分析与数据科学 python论坛
2441 3
2020-09-09

好多天没有按部就班地学习,这几天进行了高强度地探究实践:

上周天下午接了一个单子,客户目前重复做着一项工作,没有技术含量但特别消耗心理能量:

每天从固定网站上下载200多份文件,操作只是“查询--点另存为--修改文件名--保存”。不描述客户感受,大家脑补吧。

一直认为自己的主战场应该是用python做数据分析吧,但我遇到类似的重复工作时,写过一些脚本,完美地解决过问题,所以答应客户试试。

详情不述,说说过程中遇到的问题和解决方案吧:

问题1:“另存为”弹窗不出来的问题我在使用python+selenium+Chrome模拟下载数据时,我的机器居然不弹出任何“另存为”的窗口,而是以默认名称和默认路径直接下载。这就无法按客户要求修改文件名和路径了。此后发现,我每次打开的Chrome浏览器,和我日常用的浏览器设置不同,“下载前询问每个文件的保存位置”的开关每次打开都是关闭的。查了资料,原因是:为提升速度,selenium每次打开的浏览器都是初始的开净浏览器,想要修改,需要设置webdriver.ChromeOptions()的参数。

【难度级别】:高。

原因:网上没有对python如何修改“下载前询问每个文件的保存位置”的现成答案。(环境:python+selenium+Chrome)


【解决方案】:

直接上脚本了:

options = webdriver.ChromeOptions()
pref = {' 'download.default_directory': r'd:\downLoad',
         
"download.prompt_for_download": True}
options.add_experimental_option('prefs', pref)
browser = webdriver.Chrome(chrome_options = options)

【说明】:

1、'download.default_directory': r'd:\downLoad'  该语句解决下载的默认路径修改问题

2、"download.prompt_for_download": True    解决“下载前询问每个文件的保存位置” 的开关问题的,True为开

3、webdriver.Chrome(chrome_options = options)  这一点,网上有人写成webdriver.Chrome(options = options) ,网上这样的写法,我这儿调试不通过,一直报参数错误。所以这一点一定要注意哦。这个可能和webdriver的版本有关,我后来又试了,在另一台电脑上,会报“chrome_options = options”的warning,而options = options却能成功执行。


问题2:python+selenium怎么处理修改“另存为”弹窗参数的问题
窗口弹出后,我发现弹出的“另存为”页面,好像不是模拟浏览器的子窗口,是不可以通过browser.switch_to.frame()这样的切换子窗口的方法解决问题的。百度了几乎一下午的时间,没有解决问题。

无意间和爱人聊起来这个问题,爱人说,那当然不能通过这种方式解决了,这个弹窗与模拟浏览器无关,是windows系统的组件。

OK,这个思路非常重要,沿着这个思路重新百度,发现了大量资料。输入“python win32ui 修改另存为对话框”的关键字,会出现很多资料,而且非常详细。感谢!


【解决方案】:

用win32gui捕获到弹出的窗口,用spy++工具查看窗口中控件的类及父窗口的类,再用win32gui的SendMessage()传递需要修改的文件名。


notPad = win32gui.FindWindow('#32770', u'另存为')  
######################################## 修改文件名,下面的各个类,是用spy++这个工具查来的。有的不能完全照搬,可能和弹出的窗口有关。
a1 = win32gui.FindWindowEx(notPad, None, "DUIViewWndClassName", None)
a2 = win32gui.FindWindowEx(a1, None, "DirectUIHWND", None)
a3 = win32gui.FindWindowEx(a2, None, "FloatNotifySink", None)
a4 = win32gui.FindWindowEx(a3, None, "ComboBox", None)
hwnd_filename = win32gui.FindWindowEx(a4, None, "Edit", None)
time.sleep(2)
left2, top2, right2, bottom2 = win32gui.GetWindowRect(hwnd_filename)
win32api.SetCursorPos([left2, top2])
win32api.mouse_event(win32con.MOUSEEVENTF_LEFTUP | win32con.MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0)
win32gui.SendMessage(hwnd_filename, win32con.WM_SETTEXT, None, id)time.sleep(2)
'''
######################################## 按保存
hwnd_save = win32gui.FindWindowEx(notPad, None, "Button", u'保存(&S)')
win32gui.PostMessage(hwnd_save, win32con.WM_KEYDOWN, win32con.VK_RETURN, 0)

【说明】:

1、win32gui.FindWindow('#32770', u'另存为')  该句中的类为#32770,但从spy++中查到的类为“#32770 (对话框)”, 我在这儿花了好长时间,类名写不对,窗口就找不到。

2、time.sleep()  个人认为比较重要,太快了,系统还没有反映过来呢,容易获得不到需要的数据。最好时间多设几秒,因为生成EXE文件后,可能比在pycharm中执行的还要快,很容易出现规定的动作没有执行,下一个动作又开始了,最终因异常动作导致程序不能正常运行。




二维码

扫码加我 拉你入群

请注明:姓名-公司-职位

以便审核进群资格,未注明则拒绝

全部回复
2020-9-12 13:00:20
二维码

扫码加我 拉你入群

请注明:姓名-公司-职位

以便审核进群资格,未注明则拒绝

2020-10-15 09:27:47
二维码

扫码加我 拉你入群

请注明:姓名-公司-职位

以便审核进群资格,未注明则拒绝

2025-3-19 14:14:22
感谢大佬,写的好详细,您爱人也是做这方面的吗,感觉能和另一半一起讨论工作上的难题好幸福
我是刚出来工作写脚本,对这方面都是只有简单了解,这次脚本设计的就是打开插件还有另存为窗口,解决这些真的非常麻烦,我之前也有打包程序,但是脚本真的很难在别的电脑上完全复现,尤其是存在不同的分辨率以及不同设置,为了脚本能在别的电脑上运行我真的是加了好多东西,尤其是这是我第一份正式工作的第一个任务,已经因为浏览器设置不同所以跑不出来返工了好几次了,真的好崩溃。
我是希望通过设置设置webdriver.ChromeOptions()的参数。来实现另存为,但是又和我其他的代码存在冲突只能通过别的地方来调整。
也是看了您的说明才知道time.sleep() 需要多几秒,怪不得我自己电脑上运行就正常去别的电脑就操作过快没反应过来
我这里设置了另存为的程序,但是还是只能在我的电脑上跑,别人的不行,现在还在调整中。。。
你的建议真的让我受益匪浅,也让我对解决这些问题充满了信心。我会继续努力,争取尽快让脚本在不同电脑上都能稳定运行。
二维码

扫码加我 拉你入群

请注明:姓名-公司-职位

以便审核进群资格,未注明则拒绝

相关推荐
栏目导航
热门文章
推荐文章

说点什么

分享

扫码加好友,拉您进群
各岗位、行业、专业交流群