Phantom.js登录Instagram页面

7

我尝试使用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/


你是否正确设置了头部和凭据?最重要的是,所有这些查询选择器是否在网页上下文中? - marmeladze
2
你找到解决问题的方法了吗?我也遇到了同样的问题,但是找不到解决方案。 - Ritik Saxena
2
@Vaviloff,它没有将“instagram.png”保存在我的当前目录中。 - Ritik Saxena
@RitikSaxena 请在 page.render 方法内指定保存图像的目录。例如:page.render('/home/ritik/instagram.png'); 或者 page.render('C:\\Users\\Ritik\\instagram.png'); - Vaviloff
2
@RitikSaxena,我已经解决了在Linux上脚本无法运行的问题,请查看我的更新/编辑。您不必费心使用SlimerJS和xvfb。 - Vaviloff
显示剩余2条评论
1个回答

6

更新:请参见下面的编辑

我不认为

PhantomJS无法处理该页面

很可能是我们没有好好模拟真实浏览器。

快速搜索“instagram登录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命令行选项运行时,有一个详细模式可以告诉你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

我已经测试过了,但不幸的是,脚本无法工作 :'( - user4535610
请更具体地说明它的哪个方面出了问题。我已经在Win 7 x64上使用PhantomJS 2.1.1进行了测试,生成的“instagram.png”包含了我在Chrome中登录后看到的内容。 - Vaviloff
./phantomjs ins.js >/dev/stdout - on Debian 8 (64 bit) doesn't work. phantomjs 2.1.1 - user4535610
PhantomJS没有退出,也没有生成instagram.png - user4535610
2
是的,存在问题。即使在Ubuntu服务器上运行一个最小的示例来打开登录页面并截取屏幕也无法正常工作。很有趣,稍后会尝试进行调试。 - Vaviloff
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接