【问题标题】:How to simulate mobile environment with Node.js?如何使用 Node.js 模拟移动环境?
【发布时间】:2017-01-09 07:51:47
【问题描述】:

我想使用Node.js 模拟移动浏览器,这意味着所有移动浏览器功能都应该在JavaScript 端(在客户端)可用,即使它们被模拟。

网页应该认为它们是在移动环境中加载的。例如,如果我们有一个网页,上面写着:

if ('ontouchstart' in window) {
  document.body.innerHTML = "Mobile";
} else {
  document.body.innerHTML = "Not mobile";
}

...那么在模拟加载页面时,body内容应该是Mobile

这样做的正确方法是什么?我会避免简单地使用 PhantomJS(或任何类似的东西)执行一个脚本:

window.ontouchstart = function () {};

我正在考虑使用JSDom,但看起来没有简单的方法可以只说mobile:true,它会添加所有这些属性。

创建一个可以暴露这些APIs、模拟移动浏览器的浏览器的最佳方法是什么?

一个更好的例子

在 Node.js 方面,我想与浏览器仿真进行通信并返回一些结果。假设我们有一个像这样的index.html 页面:

<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="content-type" content="text/html; charset=utf-8">
    </head>
    <body>
        <script>
        if ('ontouchstart' in window && window.orientation) {
          document.body.innerHTML = "Mobile";
        } else {
          document.body.innerHTML = "Not mobile";
        }
        </script>
    </body>
</html>

使用node-horseman(使用Phantomjs),我们可以做到以下几点:

const Horseman = require('node-horseman');
const horseman = new Horseman();

const iPhone6 = "Mozilla/5.0 (iPhone; CPU iPhone OS 6_0 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Version/6.0 Mobile/10A5376e Safari/8536.25";    

horseman
  .userAgent(iPhone6)
  .open('index.html')
  .evaluate(function () {
    return document.body.innerHTML;
  })
  .then(html => {
      console.log(html);
  })
  .evaluate(function () {
    return navigator.userAgent;
  })
  .then(ua => {
      console.log(ua);
  })
  .close();

这会输出Not mobile,而用户代理是我提供的(iPhone 6)。预期为Mobile

它只是表明window.orientation 不可用,因为它不是移动浏览器。

【问题讨论】:

  • 你说你想让node.js模拟一个移动浏览器是什么意思?由于 node.js 通常是等式的服务器端,因此您要做什么并不明显?您的意思是您想使用 node.js 向其他站点发出请求,并且您希望其他站点认为来自您的 node.js 应用程序的请求是移动浏览器?
  • @jfriend00 没错!一般来说,对于普通浏览器,我一直在使用 PhantomJS 和 Electron,但是为了模拟移动环境,我不知道什么是最好的方法。
  • 请编辑您的问题,更清楚地说明您想要做什么。
  • @jfriend00 我添加了一个小例子。简而言之:我想看看移动浏览器加载的页面会发生什么,但从 Node.js 执行此操作(显然只是模拟功能)。
  • 而且,当您说模拟移动浏览器时,您想通过该模拟来完成什么?担心'ontouchstart' in window 之类的事情是客户端检测,并且仅在您要实际运行返回移动页面的 javascript 时才相关。你想这样做吗?如果您只是希望您发出请求的服务器认为它正在为移动浏览器提供页面,那么您可能只需要在请求上设置正确的标头(例如用户代理)并支持 cookie(以防网站cookie 你它认为你是移动的)。

标签: javascript node.js mobile


【解决方案1】:

只是 2021 年的更新:

要使用 selenium-webdriver 的仿真模式,现在正确的做法是:

var webdriver = require('selenium-webdriver'),

var driver = new webdriver.Builder()
.forBrowser('chrome')
.setChromeOptions(new chrome.Options()
.setMobileEmulation({deviceName: 'Apple iPhone 5'})
//.setMobileEmulation({deviceName: ‘Pixel 2 XL’})         //<--- tested
//.setMobileEmulation({deviceName: ‘Google Nexus 7’})
//.addArguments('start-maximized')
)
.build();

//Rest of the operations will be done in emulation mode
// this links shows what user agent you are currently using
driver.get('https://www.whatismybrowser.com/detect/what-is-my-user-agent');

driver.quit();

【讨论】:

  • 1.您需要声明 chrome const chrome = require('selenium-webdriver/chrome'); 2. 您需要将名称从 Apple iPhone 5 更改为 iPhone 5
【解决方案2】:

正如您提到的 Phantom 和 Horseman,我相信您想要一个支持移动设备的浏览器自动化框架。您可以将 selenium 与 chrome (ChromeDriver) 一起使用而不是 Phantom,并且 chrome 支持移动仿真。

在这里你可以找到 NodeJS 的 selenium 客户端:https://www.npmjs.com/package/selenium-webdriver 硒的铬驱动程序:https://sites.google.com/a/chromium.org/chromedriver/

在移动仿真模式下启动 chrome:

var webdriver = require('selenium-webdriver');
var capabilities = {
    browserName: 'chrome',
    chromeOptions: {
        mobileEmulation: {
            deviceName: 'Apple iPhone 6'
        }
    }
};

var driver = new webdriver
    .Builder()
    .withCapabilities(capabilities)
    .build();

您可以在此处找到可用设备列表:https://stackoverflow.com/a/41104964/893432

您还可以定义您的自定义设备:https://sites.google.com/a/chromium.org/chromedriver/mobile-emulation

如果您希望它无头,最新的 chrome 版本支持它: https://chromium.googlesource.com/chromium/src/+/lkgr/headless/README.md

您还可以使用 selenium 在真正的 android 设备或模拟器上运行测试: https://sites.google.com/a/chromium.org/chromedriver/getting-started/getting-started---android

【讨论】:

  • 这看起来不错,但恐怕这在没有 GUI 的服务器上不起作用。
  • @IonicăBizău 正如我提到的,您可以在无头模式下运行 chrome:chrisle.me/2013/08/running-headless-selenium-with-chromegist.github.com/addyosmani/5336747
  • 那就更好了!是否可以以类似的方式在无头模式下运行 Android?谢谢!
  • @IonicăBizău 你可以在无头模式下运行 android 模拟器 paulemtz.blogspot.com/2013/05/… 然后使用 selenium 连接到它的 chrome!
  • 谢谢。您可以添加设置此环境的步骤吗?听起来不是一个简单的任务,而且那个帖子已经有 4 年历史了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-04-08
  • 1970-01-01
  • 2021-11-30
  • 1970-01-01
  • 2013-11-16
  • 1970-01-01
  • 2014-06-22
相关资源
最近更新 更多