This is a question about PHP, cURL, preg_match(), RegEx, and Instagram.
I'm trying to write a cURL PHP code that logs-in to Instagram, and then access content only available to a validated (logged-in) user. In this question there's an interesting code just for that.
I copy-pasted the code, which is the following:
<?php
$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);
?>
You must, of course, change the $username's value from yourname to an actual username, and $password's value from yourpass to the corresponding password of the username. Also, I don't think this code will work if 2-step authentication is enabled in the account of the user (ie., for example, a MMS is sent to the linked phone number, or an email is sent to the linked email), therefore, 2-step authentication must be disabled in the user's account settings.
However, when I run this PHP script in Chrome, I get the message Failed to find log in form!, meaning that, on line 35, the pattern (written as a RegEx) /<form method="POST" id="login-form" class="adjacent".*?<\/form>/is wasn't found in the variable $page, which at the same time is basically the HTML of the classic Instagram login page.
It's weird that such pattern is not being found, because there's indeed a HTML named <form method="POST" id="login-form" class="adjacent" (to check it yourself, go to the login page, press Ctrl+U, then Ctrl+F, and then paste the previous pattern). So, I assume this is because the RegEx is somehow misspelled. Is that correct?
Even weirder, I tested it on the page RegEx101.com, and the test was successful. So, why is PHP saying the pattern wasn't found?
The idea is that the pattern can be found in the code of the original question, so that I can log-in automatically/programmatically. Keep in mind that more preg_match() functions are used later in the code, eg. on lines 42, 48 (preg_match_all()), 70 (preg_match_all()), and 137 (preg_match_all()).
EDIT: I realized that if I add var_dump($page); just before line 35, I get bool(false) (in other words, the HTML output is bool(false) Failed to find log in form!). I think this is the reason why the code returns the message Failed to find log in form!. However, why is the value of $page returning that?

