Selenium (已解决) python+selenium 如何优雅地处理出现未知次数的弹框 (另一个奇怪的问题)?

maybe-why-not · 2019年10月20日 · 3461 次阅读

问题:解决如何处理出现未知次数的弹框的问题,以下代码是从我的部分代码中提取出来的。希望在普通的无弹框网页,和遇到特殊情况如 https://awp.taobao.com/bs/wwlight.html?ver=3&touid=tdkefu&siteid=cntaobao&status=2&charset=utf-8(alert 有时候 3 次有时候 4 次)的时候都能继续运行(我的目标是写通用全站动态爬虫(包含各种 select、click button),不指定目标,能用第一,性能第二,但能不一直 for try 就不 for try)。下面是我的坎坷经历,在此期间我尝试 Google 或看文档找方法,但是这些 except 情况奇怪的我找不到解决方法。有点长,请大佬们不要觉得烦躁。

2019-10-03

13 天前我在这里提问,被 “如何优雅地处理出现未知次数的弹框” 所困扰,popups.html 代码如下:

<script>alert(1)</script>
<script>prompt(1)</script>
<script>confirm(1)</script>
<a href="https://www.baidu.com" target="_blank">baidu</a>

以上代码中的弹框出现未知次数(0-n),要求出现若干次弹框,最后均能正确返回 driver.find_elements_by_xpath("//a") 的结果

我的尝试:
driver.execute_script('window.alert=function(str){return;};'),这样重写不能实现目标。

from selenium import webdriver111

chromeOptions = webdriver.ChromeOptions()
prefs={"profile.managed_default_content_settings.popups":0}
chromeOptions.add_experimental_option('prefs',prefs)
driver = webdriver.Chrome(chrome_options=chromeOptions)

domain = 'file:///C:/Users/admin/Desktop/popups.html'
driver.get(domain)

这样配置也不能实现目标。

我的处理代码已经跟我一样炸裂,就不发了。
我知道自定义 chromium 能实现禁止弹框,但还不想中途学习 chromium 源码编译。。。

并不优雅的解决方案:
由于在有弹框的时候,在 try 下执行 links = driver.find_elements_by_xpath("//a"),会报错

selenium.common.exceptions.UnexpectedAlertPresentException: Alert Text: 1

同时弹框自动消失,若此时执行 driver.switch_to.alert.accept(),会触发不存在弹框的错误:

selenium.common.exceptions.NoAlertPresentException: Message: no such alert

所以我决定不对弹框进行操作,并不优雅的解决方案如下:

from selenium import webdriver

driver = webdriver.Chrome()
domain = 'file:///C:/Users/admin/Desktop/popups.html'
driver.get(domain)

for i in range(0,5):#允许弹框出现的次数一直循环的直接放弃
    try:
        links = driver.find_elements_by_xpath("//a")
        break
    except Exception as e:
        if 'alert' in str(e):
            pass
        else:
            links = []
            break

print(links)

2019-10-20

今天这个解决方法在 https://awp.taobao.com/bs/wwlight.html?ver=3&touid=tdkefu&siteid=cntaobao&status=2&charset=utf-8 上失效了,同样的代码在命令行上运行能成功把 alert 都点掉,但是把代码复制到测试.py 文件运行就不行了。
代码:

from selenium import webdriver

driver = webdriver.Chrome()
domain = 'https://awp.taobao.com/bs/wwlight.html?ver=3&touid=tdkefu&siteid=cntaobao&status=2&charset=utf-8'
driver.get(domain)

def get_url():
    for i in range(0,5):#允许弹框出现的次数,一直循环的直接放弃
        try:
            links = driver.find_elements_by_xpath("//a")
            break
        except Exception as e:
            print(str(e))
            if 'alert' in str(e):
                pass
            else:
                links = []
                break
    return links

print(get_url())

命令行:

测试.py:

在测试.py 的情况下,访问 https://awp.taobao.com/bs/wwlight.html?ver=3&touid=tdkefu&siteid=cntaobao&status=2&charset=utf-8 ,然后一句 links = driver.find_elements_by_xpath("//a") 触发错误:

File "E:\Python36\lib\site-packages\selenium\webdriver\remote\errorhandler.py", line 241, in check_response
    raise exception_class(message, screen, stacktrace, alert_text)
selenium.common.exceptions.UnexpectedAlertPresentException: Alert Text: 检测到你未安装阿里旺旺客户端,是否要跳转到官网下载?
Message: unexpected alert open: {Alert text : 检测到你未安装阿里旺旺客户端,是否要跳转到官网下载?}
  (Session info: chrome=77.0.3865.120)

之后这个浏览器就直接失控,像 driver.quit(),driver.get(),driver.switch_to.alert.accept(),ctrl+t 等之类的操作全部只会返回这个错误:

File "E:\Python36\lib\site-packages\urllib3\util\retry.py", line 399, in increment
    raise MaxRetryError(_pool, url, error or ResponseError(cause))
urllib3.exceptions.MaxRetryError: HTTPConnectionPool(host='127.0.0.1', port=55515): Max retries exceeded with url: /session/83da31a3effc9996f776f938e863edf9/url (Caused by NewConnectionError('<urllib3.connection.HTTPConnection object at 0x0000028279BCFB70>: Failed to establish a new connection: [WinError 10061] 由于目标计算机积极拒绝,无法连接。',))

测试.py 与命令行运行结果不一样、浏览器失控的情况,这个神奇的网页,一整天把我头都想烂了。

2019-10-21
另一个同学运行了就可以了,ChromeDriver 版本不兼容的 bug,我用的版本 76.0.3809.25,同学的是 2.43.600210。(chrome 77.0.3865.120)
发现连带 2019-10-03 的解法都是建立在版本 bug 的基础上了。。

共收到 0 条回复 时间 点赞
maybe-why-not 关闭了讨论 10月21日 11:14
需要 登录 后方可回复, 如果你还没有账号请点击这里 注册