如何使用 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_is
、title_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 中恢复的人数的类路径