【问题标题】:How can I get a intermediate URL from a redirect chain from Selenium using Python?如何使用 Python 从 Selenium 的重定向链中获取中间 URL?
【发布时间】:2016-06-06 04:17:58
【问题描述】:

我正在使用 Selenium 和 Python API 和 Firefox 来做一些自动的事情,这是我的问题:

  1. 点击原始页面上的链接,比如说在页面 a.com
  2. 我被重定向到 b.com/some/path?arg=value
  3. 然后我立即再次重定向到最终地址 c.com

那么有没有办法使用 Selenium Python API 获取中间重定向 URL b.com/some/path?arg=value?我试过driver.current_url,但是当浏览器在 b.com 上时,似乎浏览器仍在加载中,并且只有在加载了最终地址 c.com 时才返回结果.

另一个问题是,有没有办法将一些事件处理程序添加到 Selenium 以进行 URL 更改? Phantomjs 有能力,但我不确定 Selenium。

【问题讨论】:

    标签: python selenium redirect selenium-webdriver event-handling


    【解决方案1】:

    您可以从 performance 日志中获取重定向。根据docsgithub answer,这是我在 C# 中所做的,应该可以移植到 Python 中:

    var options = new ChromeOptions();
    var cap = DesiredCapabilities.Chrome();
    var perfLogPrefs = new ChromePerformanceLoggingPreferences();
    perfLogPrefs.AddTracingCategories(new string[] { "devtools.network" });
    options.PerformanceLoggingPreferences = perfLogPrefs;
    options.AddAdditionalCapability(CapabilityType.EnableProfiling, true, true);
    options.SetLoggingPreference("performance", LogLevel.All);
    var driver = new ChromeDriver(options);
    var url = "https://some-website-that-will-redirect.com/";
    driver.Navigate().GoToUrl(url);
    var logs = driver.Manage().Logs.GetLog("performance"); //all your logs with redirects will be here
    

    循环通过logs,如果message.params.redirectResponse.url等于原始URL,那么message.params.request.url将包含重定向URL

    【讨论】:

      【解决方案2】:

      回答我自己的问题。

      如果重定向链很长,可以考虑尝试@alecxe 和@Krishnan 提供的方法。但在这种特定情况下,我发现了一个更简单的解决方法:

      当页面最终登陆 c.com 时,使用 driver.execute_script('return window.document.referrer') 获取 中间网址

      【讨论】:

        【解决方案3】:

        可以将 BrowserMob 代理等代理服务器设置到您的 Selenium 测试中,然后通过代理服务器路由您的网络流量。流量信息全部捕获为HAR文件。您可以尝试通过插入代理服务器来获取此信息,例如BrowserMob Proxy

        AFAIK Selenium 提供的唯一侦听钩子是EventFiringWebDriver,您可以在其中通过 EventFiringWebDriver 中的register 方法扩展AbstractWebDriverEventListener 来插入您自己的事件侦听。但是 EventFiringWebDriver 有限制。它不能窃听来自 Actions 类的事件。还有一个替代方案。前一段时间,我创建了一篇讨论它的博客文章。也许你也可以参考一下。这是link

        我不知道 Python 中是否有类似的情况(因为我从未使用过 Selenium Python 绑定)

        【讨论】:

        • 感谢您提供的有用信息,我会看看。但就我而言,我找到了一种解决方法来获取正确的 URL :-)
        【解决方案4】:

        有没有办法使用 Selenium Python API 获取中间重定向 URL b.com/some/path?arg=value?

        我会使用带有小轮询间隔的Explicit Wait。我们的想法是在初始页面上等待 body 元素的陈旧

        from selenium.webdriver.common.by import By
        from selenium.webdriver.support.ui import WebDriverWait
        from selenium.webdriver.support import expected_conditions as EC
        
        body = driver.find_element_by_tag_name("body")
        
        wait = WebDriverWait(driver, 5, poll_frequency=0.05)
        wait.until(EC.staleness_of(body))
        print(driver.current_url)
        

        您可能还需要减少页面加载超时

        driver.set_page_load_timeout(0.5)
        

        另一个问题是,有没有办法将一些事件处理程序添加到 Selenium 以进行 URL 更改?

        这正是这些显式等待的内容。有相关的title_istitle_contains 预期条件,并且很容易编写您的custom one(例如,等待当前 URL 中的某些子字符串)。

        【讨论】:

        • 我用等待条件 EC.title_contains 尝试了你的方法,但它不起作用。我猜的原因是浏览器在地址 b.com 上时仍在加载,这使得等待条件永远挂起。
        • @shizhz 好的,您能否提供一种方法让我们重现问题(也许,显示您拥有的代码和所需的结果)?谢谢。
        • 谢谢。我为我的情况找到了一种解决方法:当页面最终登陆 c.com 时,我使用 driver.execute_script('return window.document.referrer') 获取之前的 URL。
        猜你喜欢
        • 1970-01-01
        • 2021-11-25
        • 2011-06-21
        • 1970-01-01
        • 1970-01-01
        • 2022-01-09
        • 2014-12-09
        • 1970-01-01
        相关资源
        最近更新 更多