5

I've written this PhantomJS script to automate signing in to Instagram. It can successfully fill in the form fields and press the submit button, but it always gets redirected back to the logon screen with the following message:

Your username or password was incorrect.

I am 100% positive that the credentials are correct, and I tried it with multiple Instagram accounts.

I'm running the script on a Mac from terminal:

$ phantomjs --ssl-protocol=any --cookies-file=cookies.txt script.js username password

Note the --ssl-protocol=any option. Without it PhantomJS can't even open the login page because of HTTPS. See this question.

Here's the code. I based it off this tutorial, and updated the code to account for the recent changes in the source code of Instagram's login page.

var system = require('system');
var username = system.args[1];
var password = system.args[2];
var page = require('webpage').create();

page.open('https://instagram.com/accounts/login/',
    function (status) {
        if (status === "success") {
            page.evaluate(function (uid, pwd) {
                var username_field = document.getElementById('lfFieldInputUsername');
                username_field.value = uid;
                var password_field = document.getElementById('lfFieldInputPassword');
                password_field.value = pwd;
            }, username, password);

            var point = page.evaluate(function () {
                var element = document.getElementsByTagName('button')[0];
                var rect = element.getBoundingClientRect();
                return {
                    x: rect.left + Math.floor(rect.width / 2),
                    y: rect.top + Math.floor(rect.height / 2)
                };
            });
            page.render('before-submit.png');
            page.sendEvent('click', point.x, point.y);
        }
        setTimeout(function () {
            var error = page.evaluate(function () {
                var element = document.getElementById('errorAlert');
                var error_message = false;
                if (element !== null) {
                    error_message = element.innerText.trim();
                }
                return error_message;
            });

            page.render('after-submit.png');
            if (!error) {
                console.log('Login Successful: ' + page.url);
            } else {
                console.log('Login Failed: ' + error);
            }

            phantom.exit(0);
        }, 5000);
    }
);

And here's what I've tried so far:

  1. Setting cookies. Besides adding the --cookies-file=cookies.txt command line option, I've also tried phantom.addCookie in the code. Didn't seem to make any difference.
  2. Explicitly sending auth headers. See this question.
  3. Changing the timezone. Not sure if this makes sense. See this question.

Apparently PhantomJS has some issues with SSL. Should I just give up using it for this purpose?

Community
  • 1
  • 1
Euripedes
  • 53
  • 7

1 Answers1

0

I think that problem with Instagram login is ReactJs. When You set value of text field, React doesn't change state. It means that login and password sending empty when you submit form.

I didn't try, but I think you should fill text inputs with keypress event, because internal component (React) state only changing when inputs text changing. Setting value in you way will not trigger change event.

Dmitry Z.
  • 424
  • 6
  • 16
  • 1
    Thank you! Works perfectly now. I have made the necessary adjustments to the script and published it on Github - [link here](https://github.com/eafreitas/autoig) – Euripedes Oct 12 '15 at 16:54
  • @Euripedes Very glad to help you. It was hard for me to figure out that every input change should be placed in separate page.evaluate. – Dmitry Z. Oct 12 '15 at 19:32