使用铬和硒进行网络节流

Posted

技术标签:

【中文标题】使用铬和硒进行网络节流【英文标题】:Network throttling with chrome and selenium 【发布时间】:2015-03-09 00:13:01 【问题描述】:

Google Chrome 38 在 devtools 中引入了新的 "Device Mode & Mobile Emulation" 功能。除了选择设备进行仿真,还可以emulate different network conditions:

在不同的网络条件下优化您的网站的性能是 为移动受众开发的一个关键方面。

设备模式的网络调节允许您在一个 各种网络连接,包括 Edge、3G,甚至离线。 从预设下拉列表中选择一个连接以应用网络 节流和延迟操作。

例如,我们可以将它设置为像过去一样 - GPRS 50 Kbps:

现在我们有了一个很好的用例——我们有一个用于网络速度测试的内部应用程序。而这个新的仿真功能对于手动测试非常有帮助。但是,我们希望将其自动化。

问题是:

是否可以通过 selenium 在指定的网络条件下启动 chrome?是否可以通过 chrome 首选项或命令行参数进行控制?


simulate slow internet connection 肯定有多种选择,但问题具体是关于 chrome+selenium。

【问题讨论】:

【参考方案1】:

控制网络模拟 were added 到 ChromeDriver 的 API。现在应该可以使用很长一段时间了。根据链接问题中的comment,由于一些错误修复,您应该使用至少 2.26 版本。

根据 Selenium changelog 绑定可用于这些语言:

javascript 自版本 3.4.0 (commit) Python 版本 3.5.0 (commit) Ruby 版本 3.11.0 (commit) C# 版本 4 (commit)

如果您需要其他语言的这些绑定,您可能应该打开类似于上述之一的问题/贡献实现。

Python 的示例用法如下:

driver.set_network_conditions(
    offline=False,
    latency=5,  # additional latency (ms)
    download_throughput=500 * 1024,  # maximal throughput
    upload_throughput=500 * 1024)  # maximal throughput

【讨论】:

download_throughput 和 upload_throughput 是每秒字节数吗?那么示例大概是 5MB/s? @Cynic 在 Chrome 开发工具中显示kb/s。我的假设是使用 API 时是一样的。但我没有测试过自己。如果/当你弄清楚时,请编辑答案。 这很奇怪。如果我使用开发工具将其打开并输入 5 * 1024 并在speedtest.xfinity.com 进行测试(易于找到开始按钮)我得到 5 mbps。但是如果我在 Selenium 脚本中做同样的事情,5 * 1024 它基本上不会注册。为了获得大约 5 mbps,我需要做一些大约 5 * 30000 的事情来获得大约 5 mbps 的东西(如果我不限制脚本而不是互联网,则在 300 mbps+ 上)。也许是一个错误,因为这与我能想到的任何转换都不太对应。 根据 ChromeDriver 代码here 中的 cmets,当您覆盖网络条件时,您会以 bps 为单位提供吞吐速度,即使预设以 kbps 为单位列出。class="comcopy">跨度> 据我所见,download_throughput 的输入似乎以每秒字节数为单位。不是比特。我可能疯了,但数字似乎是这样计算的。因此,如果您想要 500 kbps:download_throughput=500 / 8 * 1024, 让我知道是否有其他人看到相同的速度。有点难以确定地衡量。【参考方案2】:

不,无法通过 Chrome 首选项或命令行参数控制 Network Connectivity Emulation。网络连接仿真是内置 Chrome 调试器的一部分。解决此问题的一种方法是控制调试器。这可以通过扩展或直接控制调试器来完成,请参阅explanation。但是,这不适用于 WebDriver。原因是只能有一个“调试”会话并且 WebDriver 已经在使用它,请参阅explanation。由于没有公共接口,也无法通过WebDriver进行控制。

Device Mode & Mobile Emulation 也是内置调试器的一部分,有一个公共接口 (details),因此可以进行控制。这可以通过 WebDriver Capabilities 来完成。两个选项 1) 指定设备名称 2) 输入您自己的参数(有限)。

【讨论】:

【参考方案3】:

您可以使用此方法在指定的网络条件下运行您的测试用例

protected void networkThrotting() throws IOException 
  Map map = new HashMap();
  map.put("offline", false);
  map.put("latency", 5);
  map.put("download_throughput", 500);
  map.put("upload_throughput", 1024);


  CommandExecutor executor = ((ChromeDriver)driver).getCommandExecutor();
  Response response = executor.execute(
        new Command(((ChromeDriver)driver).getSessionId(),    "setNetworkConditions", ImmutableMap.of("network_conditions", ImmutableMap.copyOf(map)))
  );

【讨论】:

【参考方案4】:

C# Selenium 最新版(3.11)确实添加了 NetworkConditions。现在你可以像这样使用它了:

     var driver = new ChromeDriver(pathToDriver);
     driver.NetworkConditions = new ChromeNetworkConditions()
       DownloadThroughput = 5000, UploadThroughput = 5000, Latency = TimeSpan.FromMilliseconds(5) ;

问题是因为这个bug,它还不能使用

https://github.com/SeleniumHQ/selenium/issues/5693

所以.Net 的人必须等到 3.12 Selenium 发布。

【讨论】:

【参考方案5】:

虽然这是一个非常受欢迎和有用的功能,但对于认真的测试,我认为传统的网络模拟方法仍然是可行的方法。

除了已经链接的解决方案之外,我还知道 2 个解决方案 - Charles web proxy(非常有用的工具 - 商业)和使用 Linux 流量控制实现您自己的方案(例如,参见 LAMPe2e 的第 6 章)。

通过干扰网络连接而不是浏览器,您可以独立于所使用的浏览器对影响进行适当的衡量。

您为什么只想使用 Chrome 功能?

【讨论】:

【参考方案6】:

看起来它很快就会出现在 Selenium (C#) 中。提交日期为 2018 年 1 月 28 日:

https://github.com/SeleniumHQ/selenium/blob/ef156067a583fe84b66ec338d969aeff6504595d/dotnet/src/webdriver/Chrome/ChromeNetworkConditions.cs

【讨论】:

【参考方案7】:

我知道这是一个老问题,但我最近不得不解决这个问题,这个页面出现在我的 Google 搜索顶部。以下是我在 C# 中如何做到这一点的主要内容。希望这对将来的人有所帮助。

var networkConditions = new ChromeNetworkConditions();
networkConditions.Latency = new TimeSpan(150);
networkConditions.IsOffline = false;
networkConditions.DownloadThroughput = 120 * 1024;
networkConditions.UploadThroughput = 150 * 1024;
Driver.NetworkConditions = networkConditions;

【讨论】:

【参考方案8】:

让我们考虑两种不同的方法,

一个我们可以限制整个网络的地方,一个我们可以指定具体限制哪些网络请求的地方。

方法一:限制整个网络

const  Builder  = require("selenium-webdriver")

async function throttleNetwork() 
  let driver = await new Builder().forBrowser("chrome").build();

  await driver.setNetworkConditions(
    offline: false,
    latency: 5000, // Additional latency (ms).
    download_throughput: 50 * 1024, // Maximal aggregated download throughput.
    upload_throughput: 50 * 1024, // Maximal aggregated upload throughput.
  );

  driver.get("http://www.google.com/");

感谢Yaroslav 指出提交。

这有一个缺点,我们无法指定特定的网络请求来限制,而其余的则不受限制。

让我们在下一个方法中解决这个缺点。

方法 2:限制特定的网络请求

在这里,我们将使用来自 requestly 的名为 Requestly for Selenium 的 npm 包。

我们需要先在他们的client application中创建一个规则,并通过创建一个共享列表来获取链接。

例如,让我们限制对 google.com 的网络请求

require("chromedriver");
const  Builder  = require("selenium-webdriver");
const chrome = require("selenium-webdriver/chrome");
const 
  getRequestlyExtension,
  importRequestlySharedList,
 = require("@requestly/selenium");

const sharedListUrl = "YOUR_SHARED_LIST_LINK_HERE" // For example, use "https://app.requestly.io/rules/#sharedList/1631611216670-delay"

async function throttleGoogle() 
  const options = new chrome.Options().addExtensions(
    getRequestlyExtension("chrome") // This installs requestly chrome extension in your testing instance
  );

  const driver = new Builder()
    .forBrowser("chrome")
    .setChromeOptions(options)
    .build();

  await importRequestlySharedList(driver, sharedListUrl); // Here we import the shared list we created some time back
  driver.get("http://www.google.com/");

这是对我们如何克服仅硒方法的缺点的高级概述。我已经写了一篇关于如何创建规则、共享列表等的博客。你可以阅读它here。

【讨论】:

【参考方案9】:

对于像我这样在 C# 世界中想知道为什么上传/下载吞吐量无法按预期工作的人来说,这些属性的工具提示似乎被贴错了标签。工具提示指出数据速率以 kb/s 为单位,但根据我自己的经验,它实际上是每秒字节数,因此如果您想使用更熟悉的测量方法,例如 Mbps,则必须乘以 125,000:

int latencyInMilliseconds = 20;
long downloadLimitMbps = 20;
long uploadLimitMbps = 5;
_driver.NetworkConditions = new ChromeNetworkConditions()

    Latency = new TimeSpan(0, 0, 0, 0, latencyInMilliseconds),
    DownloadThroughput = downloadLimitMbps * 125000, // Mbps to bytes per second
    UploadThroughput = uploadLimitMbps * 125000, // Mbps to bytes per second
    IsOffline = false,
;

在我的测试运行时使用这些设置并查看网络流量,我可以看到它们导致正好下降 20Mbps 和上升 5Mbps。

【讨论】:

以上是关于使用铬和硒进行网络节流的主要内容,如果未能解决你的问题,请参考以下文章

如何使用令牌和硒(python)登录不和谐

如何使用扩展和硒打开一个新的标签页?

用scrapy和硒刮去分页的内容

使用ffmpeg通过编解码器压缩后从网络摄像头获取所有字节流?

使用 lodash 的节流不使用 ReactJS 进行节流

微信小程序:防止多次点击跳转(函数节流)