Login to Instagram programmatically

I am trying to programmatically log into Instagram through my own site because I want to receive direct messages from Instagram (it requires a login as it is not supported in the Instagram API (yet)). But the Instagram login page requires cookie authorization.

I keep getting a message that the page could not be loaded and that I might need to enable cookies.

Can I connect programmatically via PHP to Instagram?

This is what I have so far.

$ch = curl_init('https://instagram.com/accounts/login/');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HEADER, 1);
$result = curl_exec($ch);
preg_match_all('/^Set-Cookie:\s*([^\r\n]*)/mi', $result, $ms);
$cookies = array();
foreach ($ms[1] as $m) {
   list($name, $value) = explode('=', $m, 2);
   $cookies[$name] = $value;
}

$ccode  = substr($cookies['ccode'], 0, 2);
$mid    = array_shift(explode(';', $cookies['mid']));
$csfrtoken = array_shift(explode(';', $cookies['csrftoken']));

$header = array();
$header[] = 'Accept: */*';
$header[] = 'Accept-Encoding: gzip,deflate';
$header[] = 'Accept-Language: nl-NL,nl;q=0.8,en-US;q=0.6,en;q=0.4';
$header[] = 'Connection: keep-alive';
$header[] = 'Content-Length: 46';
$header[] = 'Content-Type: application/x-www-form-urlencoded; charset=UTF-8';
$header[] = 'X-Instagram-AJAX: 1';
$header[] = 'X-Requested-With: XMLHttpRequest';

$ch = curl_init('https://instagram.com/accounts/login/ajax/');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, 'username=*****&password=*****&intent=');
curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.120 Safari/537.36');
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
curl_setopt($ch, CURLOPT_COOKIEJAR, dirname(__FILE__).'/test.txt');
curl_setopt($ch, CURLOPT_COOKIEFILE, dirname(__FILE__).'/test.txt');
curl_setopt($ch, CURLOPT_COOKIESESSION, true);
curl_setopt($ch, CURLOPT_COOKIE, 'mid='.$mid.'; ccode='.$ccode.'; csrftoken='.$csfrtoken.';');
curl_setopt($ch, CURLOPT_ENCODING, '');

$response = curl_exec($ch);

      

+8


source to share


5 answers


My great compliments to @Fatih Kısa for his code, very good job. I tried this code but it doesn't work so far, possibly due to some changes on the Instagram server. I played 2 days with his code and got it working with my little changes. A very important part of this code is that Instagram only accepts a postform with a curl referrer that contains cookie data (csrftoken and mid). Also the important part is that you have to use https://www.instagram.com/accounts/login/?force_classic_login , only with WWW, and delete the curl info lines after cookie creation:

HTTP CookieNetscape

#http: //curl.haxx.se/docs/http-cookies.html

# This file was generated by libcurl! Edit at your own risk.



Here is a working code, enjoy!

$username = "yourname";
$password = "yourpass";
$useragent = "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/50.0.2661.102 Chrome/50.0.2661.102 Safari/537.36";
$cookie=$username.".txt";

@unlink(dirname(__FILE__)."/".$cookie);

$url="https://www.instagram.com/accounts/login/?force_classic_login";

$ch  = curl_init();        

$arrSetHeaders = array(
    "User-Agent: $useragent",
    'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
    'Accept-Language: en-US,en;q=0.5',
    'Accept-Encoding: deflate, br',
    'Connection: keep-alive',
    'cache-control: max-age=0',
);

curl_setopt($ch, CURLOPT_HTTPHEADER, $arrSetHeaders);         
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_COOKIEJAR, dirname(__FILE__)."/".$cookie);
curl_setopt($ch, CURLOPT_COOKIEFILE, dirname(__FILE__)."/".$cookie);
curl_setopt($ch, CURLOPT_USERAGENT, $useragent);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);

$page = curl_exec($ch);
curl_close($ch);          

// try to find the actual login form
if (!preg_match('/<form method="POST" id="login-form" class="adjacent".*?<\/form>/is', $page, $form)) {
    die('Failed to find log in form!');
}

$form = $form[0];

// find the action of the login form
if (!preg_match('/action="([^"]+)"/i', $form, $action)) {
    die('Failed to find login form url');
}

$url2 = $action[1]; // this is our new post url
// find all hidden fields which we need to send with our login, this includes security tokens
$count = preg_match_all('/<input type="hidden"\s*name="([^"]*)"\s*value="([^"]*)"/i', $form, $hiddenFields);

$postFields = array();

// turn the hidden fields into an array
for ($i = 0; $i < $count; ++$i) {
    $postFields[$hiddenFields[1][$i]] = $hiddenFields[2][$i];
}

// add our login values
$postFields['username'] = $username;
$postFields['password'] = $password;   

$post = '';

// convert to string, this won't work as an array, form will not accept multipart/form-data, only application/x-www-form-urlencoded
foreach($postFields as $key => $value) {
    $post .= $key . '=' . urlencode($value) . '&';
}

$post = substr($post, 0, -1);   

preg_match_all('/^Set-Cookie:\s*([^;]*)/mi', $page, $matches);

$cookieFileContent = '';

foreach($matches[1] as $item) 
{
    $cookieFileContent .= "$item; ";
}

$cookieFileContent = rtrim($cookieFileContent, '; ');
$cookieFileContent = str_replace('sessionid=; ', '', $cookieFileContent);

$oldContent = file_get_contents(dirname(__FILE__)."/".$cookie);
$oldContArr = explode("\n", $oldContent);

if(count($oldContArr))
{
    foreach($oldContArr as $k => $line)
    {
        if(strstr($line, '# '))
        {
            unset($oldContArr[$k]);
        }
    }

    $newContent = implode("\n", $oldContArr);
    $newContent = trim($newContent, "\n");

    file_put_contents(
        dirname(__FILE__)."/".$cookie,
        $newContent
    );    
}

$arrSetHeaders = array(
    'origin: https://www.instagram.com',
    'authority: www.instagram.com',
    'upgrade-insecure-requests: 1',
    'Host: www.instagram.com',
    "User-Agent: $useragent",
    'content-type: application/x-www-form-urlencoded',
    'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
    'Accept-Language: en-US,en;q=0.5',
    'Accept-Encoding: deflate, br',
    "Referer: $url",
    "Cookie: $cookieFileContent",
    'Connection: keep-alive',
    'cache-control: max-age=0',
);

$ch  = curl_init();
curl_setopt($ch, CURLOPT_COOKIEJAR, dirname(__FILE__)."/".$cookie);
curl_setopt($ch, CURLOPT_COOKIEFILE, dirname(__FILE__)."/".$cookie);
curl_setopt($ch, CURLOPT_USERAGENT, $useragent);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, $arrSetHeaders);     
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_REFERER, $url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post);        

sleep(5);
$page = curl_exec($ch);


preg_match_all('/^Set-Cookie:\s*([^;]*)/mi', $page, $matches);
$cookies = array();
foreach($matches[1] as $item) {
    parse_str($item, $cookie1);
    $cookies = array_merge($cookies, $cookie1);
}
var_dump($page);      

curl_close($ch);  

      

+10


source


You can use the classic login form with the "force_classic_login" parameter.



<?php
    $username = "username";
    $password = "password";
    $useragent = "Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.13) Gecko/20101206 Ubuntu/10.10 (maverick) Firefox/3.6.13";
    $cookie=$username.".txt";

    $url="https://instagram.com/accounts/login/?force_classic_login";

    $ch  = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_COOKIEJAR, dirname(__FILE__)."/".$cookie);
    curl_setopt($ch, CURLOPT_COOKIEFILE, dirname(__FILE__)."/".$cookie);
    curl_setopt($ch, CURLOPT_USERAGENT, $useragent);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_HEADER, 1);
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);

    $page = curl_exec($ch);

    // try to find the actual login form
    if (!preg_match('/<form method="POST" id="login-form" class="adjacent".*?<\/form>/is', $page, $form)) {
        throw Instagram_Manager('Failed to find log in form!');
    }

    $form = $form[0];

    // find the action of the login form
    if (!preg_match('/action="([^"]+)"/i', $form, $action)) {
        throw Instagram_Manager('Failed to find login form url');
    }

    $url2 = $action[1]; // this is our new post url
    // find all hidden fields which we need to send with our login, this includes security tokens
    $count = preg_match_all('/<input type="hidden"\s*name="([^"]*)"\s*value="([^"]*)"/i', $form, $hiddenFields);

    $postFields = array();

    // turn the hidden fields into an array
    for ($i = 0; $i < $count; ++$i) {
        $postFields[$hiddenFields[1][$i]] = $hiddenFields[2][$i];
    }

    // add our login values
    $postFields['username'] = $username;
    $postFields['password'] = $password;

    $post = '';

    // convert to string, this won't work as an array, form will not accept multipart/form-data, only application/x-www-form-urlencoded
    foreach($postFields as $key => $value) {
        $post .= $key . '=' . urlencode($value) . '&';
    }

    $post = substr($post, 0, -1);

    // set additional curl options using our previous options
    curl_setopt($ch, CURLOPT_URL, "https://instagram.com/".$url2);
    curl_setopt($ch, CURLOPT_REFERER, $url);
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
   $page = curl_exec($ch);

    // connect to profile edit page
    $url="https://instagram.com/accounts/edit/";
    curl_setopt($ch, CURLOPT_URL, $url);
    echo curl_exec($ch);    
?>

      

+3


source


It looks like you are headed in the right direction, in your example it appears that you received an authenticated response, but the subsequent request for an authenticated page does not work as expected.

I suspect instagram is actively preventing this by triggering validation with an Ajax call or something similar.

Alternatively, you can look at something like zombie.js .

It is a headless virtual browser where you can visit pages and interact with elements on it, but you cannot view them.

A simple example with zombie.js looks like this:

var Browser = require('zombie');
var browser = Browser.create();

browser.visit('https://instagram.com/', function() {
  browser.wait(10000, function(){
    browser.fill('input[name="username"]', 'myusername');
    browser.fill('input[type="password"]', 'mypasswd');
    browser.pressButton('Log in', function() {
      browser.visit('https://instagram.com/accounts/edit/', function() {
        console.log(browser.html());
      });
    });

  });

});

      

Hope it helps.

+3


source


@Vaha's code stopped working

change

$cookieFileContent = str_replace('sessionid=; ', '', $cookieFileContent);

      

behind

$cookieFileContent = str_replace('sessionid=""; ', '', $cookieFileContent);

      

and the code will work


define('USERNAME', "");
define('PASSWORD', "");
define('USERAGENT', "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.181 Safari/537.36");
define('COOKIE', USERNAME.".txt");

function login_inst() {

    @unlink(dirname(__FILE__)."/!instagram/".COOKIE);

    $url="https://www.instagram.com/accounts/login/?force_classic_login";

    $ch  = curl_init(); 

    $arrSetHeaders = array(
        "User-Agent: USERAGENT",
        'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
        'Accept-Language: en-US,en;q=0.5',
        'Accept-Encoding: deflate, br',
        'Connection: keep-alive',
        'cache-control: max-age=0',
    );

    curl_setopt($ch, CURLOPT_HTTPHEADER, $arrSetHeaders);         
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_COOKIEJAR, dirname(__FILE__)."/!instagram/".COOKIE);
    curl_setopt($ch, CURLOPT_COOKIEFILE, dirname(__FILE__)."/!instagram/".COOKIE);
    curl_setopt($ch, CURLOPT_USERAGENT, USERAGENT);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_HEADER, 1);
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);

    $page = curl_exec($ch);
    curl_close($ch);  

    //var_dump($page);

    // try to find the actual login form
    if (!preg_match('/<form method="POST" id="login-form" class="adjacent".*?<\/form>/is', $page, $form)) {
        die('Failed to find log in form!');
    }

    $form = $form[0];

    // find the action of the login form
    if (!preg_match('/action="([^"]+)"/i', $form, $action)) {
        die('Failed to find login form url');
    }

    $url2 = $action[1]; // this is our new post url
    // find all hidden fields which we need to send with our login, this includes security tokens
    $count = preg_match_all('/<input type="hidden"\s*name="([^"]*)"\s*value="([^"]*)"/i', $form, $hiddenFields);

    $postFields = array();

    // turn the hidden fields into an array
    for ($i = 0; $i < $count; ++$i) {
        $postFields[$hiddenFields[1][$i]] = $hiddenFields[2][$i];
    }

    // add our login values
    $postFields['username'] = USERNAME;
    $postFields['password'] = PASSWORD;   

    $post = '';

    // convert to string, this won't work as an array, form will not accept multipart/form-data, only application/x-www-form-urlencoded
    foreach($postFields as $key => $value) {
        $post .= $key . '=' . urlencode($value) . '&';
    }

    $post = substr($post, 0, -1);   

    preg_match_all('/^Set-Cookie:\s*([^;]*)/mi', $page, $matches);

    $cookieFileContent = '';

    foreach($matches[1] as $item) 
    {
        $cookieFileContent .= "$item; ";
    }

    $cookieFileContent = rtrim($cookieFileContent, '; ');
    $cookieFileContent = str_replace('sessionid=""; ', '', $cookieFileContent);

    $oldContent = file_get_contents(dirname(__FILE__)."/!instagram/".COOKIE);
    $oldContArr = explode("\n", $oldContent);

    if(count($oldContArr))
    {
        foreach($oldContArr as $k => $line)
        {
            if(strstr($line, '# '))
            {
                unset($oldContArr[$k]);
            }
        }

        $newContent = implode("\n", $oldContArr);
        $newContent = trim($newContent, "\n");

        file_put_contents(
            dirname(__FILE__)."/!instagram/".COOKIE,
            $newContent
        );    
    }

    $arrSetHeaders = array(
        'origin: https://www.instagram.com',
        'authority: www.instagram.com',
        'upgrade-insecure-requests: 1',
        'Host: www.instagram.com',
        "User-Agent: USERAGENT",
        'content-type: application/x-www-form-urlencoded',
        'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
        'Accept-Language: en-US,en;q=0.5',
        'Accept-Encoding: deflate, br',
        "Referer: $url",
        "Cookie: $cookieFileContent",
        'Connection: keep-alive',
        'cache-control: max-age=0',
    );

    $ch  = curl_init();
    curl_setopt($ch, CURLOPT_COOKIEJAR, dirname(__FILE__)."/!instagram/".COOKIE);
    curl_setopt($ch, CURLOPT_COOKIEFILE, dirname(__FILE__)."/!instagram/".COOKIE);
    curl_setopt($ch, CURLOPT_USERAGENT, USERAGENT);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_HEADER, 1);
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
    curl_setopt($ch, CURLOPT_HTTPHEADER, $arrSetHeaders);     
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_REFERER, $url);
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $post);  
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);

    sleep(5);
    $page = curl_exec($ch);

    /*
    preg_match_all('/^Set-Cookie:\s*([^;]*)/mi', $page, $matches);
    COOKIEs = array();
    foreach($matches[1] as $item) {
        parse_str($item, COOKIE1);
        COOKIEs = array_merge(COOKIEs, COOKIE1);
    }
    */
    //var_dump($page);      
    curl_close($ch);  

}

      

+3


source


@wakha looks like you know what you're doing. Do you know a code or tool that can help me bypass Instagram's call that requires email verification on login?

0


source







All Articles