Bowen
@Bowen
Японский бог

Возможно ли с помощью Node.js/php получить скрытый контент определенной странице определенного сайта?

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

Есть обычный форум, где для просмотра темы нужна авторизация.
На странице авторизации присутствуют скрытые поля.

<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://website.com">
<input type="hidden" name="showLoginForm" value="false">

Значение в полях formOid и formOidMd5 генерируются при каждом запросе к этой странице.

Я убил два дня пытаясь это сделать, но в итоге только запутался во всем этом. Как я понял, необходимо сделать два запроса. Один на получение значений выше указанных полей, а второй на авторизацию. Как это можно сделать ?
  • Вопрос задан
  • 236 просмотров
Решения вопроса 1
nowm
@nowm
Я обычно пользуюсь DOM в PHP. Конечно, можно отдельные поля регулярными выражениями отловить, если знаешь их название, но есть большая вероятность, что у одного инпута сначала будет идти `type`, потом `name`, а у другого наоборт, и придётся для каждого инпута писать отдельный код, который будет из него вытаскивать значение. Проще воспринимать их как сущности с одинаковыми признаками и переложить парсинг на специализированные билиотеки.

Насколько я понял, судя по особенностям наименования инпутов, это был форум на базе hoop.la (не путать с hoopla). Я бы примерно так организовал парсинг:

$dom = new \DOMDocument();

libxml_use_internal_errors(true);
if (!@$dom->loadHTML('содержимое страницы в виде HTML')) {
    /** @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[@name="mainLoginForm"]');
if (!$form->length) {
    throw new \Exception('Форма не найдена');
}

$post_data = [];

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

$post_data['email'] = 'логин';
$post_data['password'] = 'пароль';

// В $post_data находятся все данные которые нужно отправлять


Суть такого подхода в том, что особенно не нужно загоняться, какие там есть поля и как они называются. Обходим все доступные инпуты в конкретной форме и засовываем их в массив, потом поверху патчим этот массив своим логином и паролем — всё, все необходимые данные, включая различные токены, у нас есть.

В каких-то других ситуациях, кроме инпутов нужно будет искать ещё и селекты, или предусматривать ситуации, когда нужно делать выбор из нескольких radio-элементов, либо предусматривать ещё более комплексные ситуации, но конкретно в случае с hoopla этого не потребуется — там одни инпуты, и они динамически с помощью JS вроде бы не модифицируются (сильно не тестировал).

Код может быть нерабочим. Я его наполовину копипастил из собственных разработок, наполовину писал прямо на Тостере. Главное, из него понятен смысл.
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
AleksandrB
@AleksandrB
Совсем недавно вывел "Hello world"
$str = '<input type="hidden" name="formOidMd5" value="0C2A68950BF4FE825888F2A32BAAB69E"> <input type="hidden" name="formOid" value="517260832138604146">';
preg_match_all('#name="formOidMd5" value="(.+?)">#is', $str, $arr);
preg_match_all('#name="formOid" value="(.+?)">#is', $str, $arr2);
print_r($arr[0][1]);
print_r($arr2[0][1]);

Что бы получить это все, используй
$arr = file_get_contents("http://example.com/");
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы