Как правильно парсить закрытые страницы на php/nodejs ?

Y
На сайте с 10.02.2019
Offline
0
888

Здравствуйте.

Есть форум, где для просмотра тем необходима авторизация.

Изначально я хотел парсить нужные мне страницы с помощью Node.js, однако, наткнулся на ряд сложностей из-за которых ничего не получилось. В итоге решил остановиться на php.

В форме авторизации, присутствуют несколько скрытых полей. Два их них динамически меняют свои значения при каждом запросе к странице авторизации, а именно formOid и formOidMd5

<input type="hidden" name="formType" value="mainLoginForm">

<input type="hidden" name="formOid" value="517260832138604146">
<input type="hidden" name="formOidMd5" value="0C2A68950BF4FE825888F2A32BAAB69E">
<input type="hidden" name="redirect" value="https://forum.site.com">
<input type="hidden" name="showLoginForm" value="false">

Чуть ниже формы, присутствует кусок js, где указанны следующие данные:

SS.Debug.referenceId = '517402317986309921-28.b86.f0cddca-db071.ps001';

SS.Ajax.getRequestParams = {"formType" : "ajaxGETRequest", "formOid" : "517402317986309921", "formOidMd5" : "65A68C7DD290DF33FAA27838690F0F56"};

Вот мой код:

<?php


//Where our cookie information will be stored (needed for authentication).
define('COOKIE_FILE', __DIR__ . '/cookie.txt');

//URL of the login form.
define('LOGIN_FORM_URL', 'https://forum.site.com/login/');

//Login action URL. Sometimes, this is the same URL as the login form.
define('LOGIN_ACTION_URL', 'https://forum.site.com/login!login/');

$str = file_get_contents(LOGIN_FORM_URL);

$dom = new \DOMDocument();

libxml_use_internal_errors(true);
if (!@$dom->loadHTML($str)) {
/** @var \LibXMLError $error */
$error = libxml_get_last_error();
if ($error->level > LIBXML_ERR_ERROR) {
throw new \Exception($error->message);
}
}

$xpath = new \DOMXPath($dom);

/** @var \DOMNodeList $form */
$form = $xpath->query('//form[@id="mainLoginForm"]');
if (!$form->length) {
throw new \Exception('Форма не найдена');
}

$post_data = [];

/** @var \DOMElement $input */
foreach ($xpath->query('.//input', $form->item(0)) as $input) {
if ($input->getAttribute('name')) {
$post_data[$input->getAttribute('name')] = $input->getAttribute('value');
}
}

$post_data['email'] = 'myMail@gmail.com';
$post_data['password'] = 'myPassword';
$post_data['formType'] = 'ajaxGETRequest';


//Initiate cURL.
$curl = curl_init();

//Set the URL that we want to send our POST request to. In this
//case, it's the action URL of the login form.
curl_setopt($curl, CURLOPT_URL, LOGIN_ACTION_URL);

//Tell cURL that we want to carry out a POST request.
curl_setopt($curl, CURLOPT_POST, true);

//Set our post fields / date (from the array above).
curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($post_data));

//Sets the user agent. Some websites will attempt to block bot user agents.
//Hence the reason I gave it a Chrome user agent.
//curl_setopt($curl, CURLOPT_USERAGENT, USER_AGENT);

//Tells cURL to return the output once the request has been executed.
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);

//Allows us to set the referer header. In this particular case, we are
//fooling the server into thinking that we were referred by the login form.
//curl_setopt($curl, CURLOPT_REFERER, LOGIN_FORM_URL);

//Do we want to follow any redirects?
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);

//Where our cookie details are saved. This is typically required
//for authentication, as the session ID is usually saved in the cookie file.
curl_setopt($curl, CURLOPT_COOKIEFILE, COOKIE_FILE);
curl_setopt($curl, CURLOPT_COOKIEJAR, COOKIE_FILE);

//Execute the login request.
curl_exec($curl);

//We should be logged in by now. Let's attempt to access a password protected page
curl_setopt($curl, CURLOPT_URL, 'https://forum.site.com/topic/bla-bla-bla');

//Use the same cookie file.
curl_setopt($curl, CURLOPT_COOKIEFILE, COOKIE_FILE);
curl_setopt($curl, CURLOPT_COOKIEJAR, COOKIE_FILE);

//Execute the GET request and print out the result.
echo curl_exec($curl);

Запрос отправляется, куки создаются, а вот в результате получаю главную страницу и без намека на то, что я авторизован.

Попробовал выше указанный код с другим форумом, где так же необходима авторизация для просмотра некоторых разделов. К счастью, с ним дела пошли куда лучше. Исходя из этого я сделал вывод, что я что-то не передаю и по этом не могу пройти авторизацию. Вот что именно, я понять так и не смог. Мучаюсь с этим кодом уже несколько дней, а так и не смог понять, что именно не так. Буду очень признателен за помощь.

ДП
На сайте с 23.11.2009
Offline
203
#1

В общем случае вам надо отправлять те же самые данные, что и бразурер все куки. заголовки в точности.

В иструментах разработчика или http-отладчиком типа fiddler можно посмотреть что передается. То, что передается скриптом можно увидеть, если использовать опцию CURLOPT_VERBOSE - будет на экран выводить отправляемые/получаемые заголовки.

Как увидите, в чем у вас отличия - так и поймёте, чего не хватает.

dimsog
На сайте с 08.08.2011
Offline
149
#2

Что-то мне подсказывает, что еще и данные по AJAX передаются, не увидел AJAX в заголовках у вас.

ihor vps -> ihc.ru

Авторизуйтесь или зарегистрируйтесь, чтобы оставить комментарий