我正在使用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。
performance
日志中获取重定向。根据文档和github的答案,这是我在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
(如 BrowserMob 代理)可以设置到您的 Selenium 测试中,然后通过代理服务器路由您的 Web 流量。交通信息全部捕获为 HAR 文件。您可以尝试通过插入代理服务器(如 BrowserMob 代理)来获取此信息
AFAIK Selenium提供的唯一监听钩子是EventFireringWebDriver,您可以通过EventFireringWebDriver中的注册方法扩展AbstractWebDriverEventListener来插入自己的事件监听。但是 EventFireringWebDriver 有局限性。它无法窃听由 Actions 类引起的事件。还有另一种选择。不久前,我写了一篇关于它的博客文章。也许你也可以参考它。这是链接
我不知道在Python中是否有类似的内容(因为我从未使用过Selenium Python绑定)
回答我自己的问题。
如果重定向链很长,请考虑尝试@alecxe和@Krishnan提供的方法。但是在这种特定情况下,我发现了一个更简单的解决方法:
当页面最终登陆 c.com 时,请使用
driver.execute_script('return window.document.referrer')
获得 中间网址
有没有办法使用 Selenium Python API 获取中间重定向 URL b.com/some/path?arg=value?
我会使用轮询间隔较小的显式等待。这个想法是等待初始页面上 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
预期条件,并且很容易编写自定义条件(例如,等待当前URL中的某个子字符串)。