javascript - Phantom.js 登录 instagram 页面

标签 javascript phantomjs

我正在尝试使用 phantom.js 登录 instagram 网站。我的第一个方法是:

document.querySelector("input[name='username']").value = "Username";
document.querySelector("input[name='password']").value = "Pass";

但是这段代码不会改变 DOM。

我的第二种方法:

document.getElementsByClassName("_kp5f7 _qy55y")[0].setAttribute("value", "Username");
document.getElementsByClassName("_kp5f7 _qy55y")[0].value = "Pass";

但是当我检查网络包时,用户名和密码字段为空。

Instagram 登录页面:https://www.instagram.com/accounts/login/

最佳答案

更新:请查看答案下方的编辑

我不这么认为

PhantomJS can't handle that page

这可能是我们在模拟真实浏览器方面做得不够好。

快速搜索“instagram login phantomjs”找到了这个有效的简洁解决方案:https://github.com/awener/instagram-login-phantomjs/blob/master/phan.js

它使用模拟“真实”按键和点击的 PhantomJS 机制。

为了以防万一,这里有一份脚本的副本。

var page = require('webpage').create();
var username = "myusername";
var password = "password";
page.viewportSize = { width: 1024 , height: 600 };
page.settings.userAgent = 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.106 Safari/537.36';

page.open('https:/instagram.com/accounts/login/', function() {

    var ig = page.evaluate(function() {
        function getCoords(box) {
            return  {
                x: box.left,
              y: box.top 
            };
        }   

        function getPosition(type, name) {
            // find fields to fill
            var input = document.getElementsByTagName(type);
            for(var i = 0; i < input.length; i++) {
                if(name && input[i].name == name)  return getCoords(input[i].getBoundingClientRect());
                else if(!name && input[i].className)    return getCoords(input[i].getBoundingClientRect()); // this is for login button
            }
        }
        return {
            user: getPosition('input', 'username'),
            pass: getPosition('input', 'password'),
            login: getPosition('button')
        };

     });

     // fill in data and press login
     page.sendEvent('click',ig.user.x, ig.user.y);
     page.sendEvent('keypress', username);

     page.sendEvent('click',ig.pass.x, ig.pass.y);
     page.sendEvent('keypress', password);
     page.sendEvent('click', ig.login.x, ig.login.y);

    // wait for response
    setTimeout(function() {
        page.render('/path/to/screenshot.png');
        phantom.exit();
    }, 5000);

});

编辑解释如何在 Linux 上运行脚本

这在 Debian/Ubuntu 上不起作用的原因是 SSL 证书问题。

当您使用 --debug=true CLI 选项运行 PhantomJS 时,会有一个详细模式告诉您 PhantomJS 正在做什么。使用它我找到了问题的原因:

[DEBUG] Network - SSL Error: "The issuer certificate of a locally looked up certificate could not be found"
[DEBUG] Network - SSL Error: "The root CA certificate is not trusted for this purpose"
[DEBUG] Network - Resource request error: QNetworkReply::NetworkError(SslHandshakeFailedError) ( "SSL handshake failed" ) URL: "https://instagramstatic-a.akamaihd.net/h1/scripts/polyfills/es5-sham.min.js/fc3c22cf2d67.js"
...

为避免此类问题,您只需运行 Phantomjs 并使用另一个 CLI 参数告诉它忽略 SSL 错误:

/pth/to/phantomjs --ignore-ssl-errors=true /path/to/script.js

关于javascript - Phantom.js 登录 instagram 页面,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41467692/

相关文章:

javascript - 网络音频 API 内存泄漏

javascript - jQuery.on ('click' ) 在 jQuery.click 之前?

ruby - 初始化' : rack-test requires a rack application, 但没有给出 (ArgumentError)

javascript - PhantomJS - 获取元素计算样式

javascript - 当字段没有名称时 CasperJS 填写表单

javascript - jquery中如何将数组json数据转换为特定的json?

javascript - JSTL 和 Javascript

javascript - 未捕获的类型错误 : Illegal invocation in Javascript (geolocation)

javascript - 如何使用 PhantomJS 提交表单?

java - Java 中的 Selenium PhantomJS 自定义 header