Casperjs谷歌登录(V2)无效

时间:2017-06-26 16:26:09

标签: javascript web-scraping phantomjs casperjs google-login

我使用casperjs(中间是如此的phantomjs)访问一些谷歌工具,但在访问它们之前,我们应该登录谷歌。对于V1 google身份验证,我们使用以下脚本:

var casper = require('casper').create();
url = 'https://accounts.google.com/ServiceLogin?passive=1209600&continue=https%3A%2F%2Faccounts.google.com%2FManageAccount&followup=https%3A%2F%2Faccounts.google.com%2FManageAccount&flowName=GlifWebSignIn&flowEntry=ServiceLogin&nojavascript=1#identifier';
casper.start(url, function() {

  this.fillSelectors('form#gaia_loginform', {
    'input[name="Email"]': 'your@email',
  }); //Fills the email box with email
  this.click("#next");

  this.wait(500, function() { //Wait for next page to load
    this.waitForSelector("#Passwd", //Wait for password box
      function success() {
        console.log("SUCCESS...");
        this.fillSelectors('form#gaia_loginform', {
          'input[name="Passwd"]': 'yourPassw',
        }); //Fill password box with PASSWORD
        this.click("#signIn"); //Click sign in button
        this.wait(500, function() {}); //Wait for it fully sigin
        casper.thenOpen('http://utility.google.com/', function() {
            this.wait(2000, function() {
                this.capture('media/status.png', undefined, {
                    format: 'png',
                    quality: 100`enter code here`
                });
            });
        });
      },
      function fail() {
        console.log("FAIL...");
      }
    );
  });
});
casper.run();

我们已经改变了操作表单和填充字段的方式,到目前为止它已经工作了。 V2身份验证的问题是无法触发鼠标事件,这意味着我们无法使用this.click(“#next”)和this.click(“#signIn”)单击。我尝试在表单上发布帖子,使用不同的鼠标事件并尝试直接操作jsaction事件。什么都行不通。

有人知道如何解决这个问题?非常感谢你!

2 个答案:

答案 0 :(得分:0)

我也尝试相同,我发现点击正在与this.click('#identifierNext');一起使用,谷歌加载器开始工作。如果您在点击截图后使用以下代码,您可以看到加载程序出现但在此之后,而不是转到密码屏幕,它将返回到电子邮件屏幕。

截图代码

this.wait(200, function(){
    this.capture('1.jpg',{
        top: 0,
        left: 0,
        width: 4608, 
        height: 3456,
        quality:20
    });
});
this.wait(100, function(){
    this.capture('2.jpg',{
        top: 0,
        left: 0,
        width: 4608, 
        height: 3456,
        quality:20
    });
});
this.wait(100, function(){
    this.capture('3.jpg',{
        top: 0,
        left: 0,
        width: 4608, 
        height: 3456,
        quality:20
    });
});
this.wait(100, function(){
    this.capture('4.jpg',{
        top: 0,
        left: 0,
        width: 4608, 
        height: 3456,
        quality:20
    });
});

但是我也无法访问密码屏幕,如果有了这个帮助,你可以随时告诉我。

答案 1 :(得分:0)

Casper使用PhantomJS,Phantom本身无法登录Google帐户登录。它似乎使用了phantomjs中不支持的任何ES6功能,它无声地失败。

也许你可以在beta phantomjs 2.5上获得更多运气。 无论如何,phantomjs不赞成使用chrome headless。正如幻影维护者Vitaly Slobodin所说 https://groups.google.com/forum/#!topic/phantomjs/9aI5d-LDuNE

好消息是你可以在无头模式下启动chrome:/opt/google/chrome/chrome --headless --disable-gpu --repl并做任何你想做的事。

您可以将--repl替换为--remote-debugging-port=9224以在任何远程代码中控制它,例如节点中的程序... 像phantomjs一样有控制它的库。 高级(如幻影):https://github.com/GoogleChrome/puppeteer 和更低级别以获得更多控制权:https://github.com/cyrus-and/chrome-remote-interface#clientdomainmethodparams-callback

目前我对木偶操作者没有运气,但是使用chrome-remote-interface我能够以谷歌帐户登录。

const CDP = require('chrome-remote-interface');
const argv = require('minimist')(process.argv.slice(2));
const file = require('fs');

// CLI Args
const url = argv.url || 'https://accounts.google.com';
const format = argv.format === 'jpeg' ? 'jpeg' : 'png';
const viewportWidth = argv.viewportWidth || 1440;
const viewportHeight = argv.viewportHeight || 900;
let delay = argv.delay || 0;
const userAgent = argv.userAgent;
const fullPage = argv.full;

// Start the Chrome Debugging Protocol
CDP(async function(client) {
  // Extract used DevTools domains.
  const {DOM, Emulation, Network, Page, Runtime} = client;

  // Enable events on domains we are interested in.
  await Page.enable();
  await DOM.enable();
  await Network.enable();

  // If user agent override was specified, pass to Network domain
  if (userAgent) {
    await Network.setUserAgentOverride({userAgent});
  }

  // Set up viewport resolution, etc.
  const deviceMetrics = {
    width: viewportWidth,
    height: viewportHeight,
    deviceScaleFactor: 0,
    mobile: false,
    fitWindow: false,
  };
  await Emulation.setDeviceMetricsOverride(deviceMetrics);
  await Emulation.setVisibleSize({width: viewportWidth, height: viewportHeight});

  // Navigate to target page
  await Page.navigate({url});

  // Wait for page load event to take screenshot
  Page.loadEventFired(async () => {
    // If the `full` CLI option was passed, we need to measure the height of
    // the rendered page and use Emulation.setVisibleSize
    if (fullPage) {
      const {root: {nodeId: documentNodeId}} = await DOM.getDocument();
      const {nodeId: bodyNodeId} = await DOM.querySelector({
        selector: 'body',
        nodeId: documentNodeId,
      });
      const {model: {height}} = await DOM.getBoxModel({nodeId: bodyNodeId});

      await Emulation.setVisibleSize({width: viewportWidth, height: height});
      // This forceViewport call ensures that content outside the viewport is
      // rendered, otherwise it shows up as grey. Possibly a bug?
      await Emulation.forceViewport({x: 0, y: 0, scale: 1});
    }

    let expr="document.querySelector('input[type=email]').value='YOUREMAIL@gmail.com';";
    expr+="document.querySelectorAll('div[role=button]')[0].click();";
    setTimeout
    let x=await Runtime.evaluate({expression: expr});
    console.log('******' + JSON.stringify(x));
    setTimeout(async function(){
    expr="document.querySelector('input[type=password]').value='YOUR_PASSWORD';";
    expr+="document.querySelectorAll('div[role=button]')[1].click()";
    x=await Runtime.evaluate({expression: expr});
    console.log('******' + JSON.stringify(x));
    x=await ( async function() {
            let expr="document.querySelector('input[type=password]')";
            return Runtime.evaluate({expression: expr});
    })()
    console.log('**' + JSON.stringify(x));
    }, 2000);
delay=5000
    setTimeout(async function() {
      const screenshot = await Page.captureScreenshot({format});
      const buffer = new Buffer(screenshot.data, 'base64');
      file.writeFile('output.png', buffer, 'base64', function(err) {
        if (err) {
          console.error(err);
        } else {
          console.log('Screenshot saved');
        }
        client.close();
      });
    }, delay);
  });
}).on('error', err => {
  console.error('Cannot connect to browser:', err);
});

参考文献: https://medium.com/@dschnr/using-headless-chrome-as-an-automated-screenshot-tool-4b07dffba79a

https://github.com/GoogleChrome/puppeteer/blob/master/docs/api.md#browserwsendpoint

https://developers.google.com/web/updates/2017/04/headless-chrome