如何使用 Python 从 Selenium 的重定向链中获取中间 URL?

Posted

技术标签:

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

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

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

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

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

【问题讨论】:

【参考方案1】:

您可以从 performance 日志中获取重定向。根据docs 和github 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。

以上是关于如何使用 Python 从 Selenium 的重定向链中获取中间 URL?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Selenium 和 Python 从文本节点中检索部分文本

如何使用来自具有特殊设置的网站的Selenium从下拉列表中选择值 - Python

如何通过 Selenium 和 Python 从 html 标签跨度获取文本

如何使用 Selenium 和 Python 查找从 covid 中恢复的人数的类路径

如何使用 Selenium Webdriver 和 Python 从这个非选择下拉菜单中选择这个元素

如何使用 Selenium Python 将鼠标从元素向上移动 9 个像素