DOMdocument, редактирование элементов - PullRequest
0 голосов
/ 19 октября 2011

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

Для этого я получаюHTML-источник с веб-сайта (с использованием cURL), затем с помощью DOMdocument я редактирую имя пользователя и пароль формы ввода с моими значениями имени пользователя и пароля, затем я вывожу это и нажимаю логин

Все должно быть в порядке, право?Да, в теории, но это не так.

Это код, который правильно делает:

$dom = new DOMdocument();
$dom->formatOutput = true;
@$dom->loadHTML( mb_convert_encoding($html, 'HTML-ENTITIES', $encoding) );

$inputs = $dom->getElementsByTagName('input');
foreach ($inputs as $input)
{
    if ($input->getAttribute('name') == $id_nameValue)
    {
    $new_input = $dom->createElement('input');

    $new_input->setAttribute('name', $id_nameValue);
    $new_input->setAttribute('value', $id_value);

    $input->parentNode->replaceChild($new_input, $input);
    }

    if ($input->getAttribute('name') == $password_nameValue)
    {
    $new_input = $dom->createElement('input');

    $new_input->setAttribute('name', $password_nameValue);
    $new_input->setAttribute('value', $password_value);
    $new_input->setAttribute('type', 'password');

    $input->parentNode->replaceChild($new_input, $input);
    }
}

echo $dom->savehtml();

Проблема, с которой я столкнулся, заключается в том, что JavaScript не загружается или не работает css,или не правильно перенаправить ...

Давайте возьмем, например, reddit: https://ssl.reddit.com/login Они имеют это для CSS

<link rel="stylesheet" href="/static/reddit.cYdhnJIJSZ0.css" type="text/css" />

вместо https://ssl.reddit.com/login/static/reddit.cYdhnJIJSZ0.css, такЯ не могу загрузить его правильно, потому что он использует мой URL-адрес, как

MY_URL.com/static/reddit.cYdhnJIJSZ0.css to find it...

То же самое относится к javascript, как

<script type="text/javascript" src="/static/jquery.js">

Или с

<form id="login_login" method="post" action="/post/login" class="user-form login-form">

это будетперенаправьте меня на MY_URL.com/post/login

Мой вопрос: как я могу сделать эту работу?Как я могу отредактировать ссылки, чтобы включить URL сайтов?Поскольку я впервые использую DOMdocument, я не знаю, как мне отредактировать форму или скрипт src ...

Так что мой конечный результат будет

<link rel="stylesheet" href="https://ssl.reddit.com/login/static/reddit.cYdhnJIJSZ0.css" type="text/css" />
<script type="text/javascript" src="https://ssl.reddit.com/login/static/jquery.js">
<form id="login_login" method="post" action="https://ssl.reddit.com/login/post/login" class="user-form login-form">

1 Ответ

1 голос
/ 19 октября 2011

Я думаю, что самый простой способ сделать это - внедрить тег base с атрибутом href, установленным в базовый URL последнего эффективного URL (URL, который в конечном итоге был выбран cURL в случае возможных перенаправлений) , Этот последний эффективный URL-адрес может быть получен с помощью cURL с помощью:

$url = curl_getinfo( $ch, CURLINFO_EFFECTIVE_URL );

В этом ответе я объяснил, как установить базовый тег с DOMDocument . Он также учитывает ситуации, когда уже есть тег base. Хотя по общему признанию, мой пример еще не ищет наличие атрибута href в теге base. Добавление этой проверки должно быть тривиальным путем использования DOMElement::hasAttribute().

редактировать
В ответ на комментарий alex2005:

Вы можете немного изменить его и сделать это:

$baseElement = $doc->createElement( 'base' );
$baseElement->setAttribute( 'href', $url );
$headElement = $doc->getElementsByTagName( 'head' )->item( 0 );

// it will automatically append, if $headElement has no firstChild (i.e. is null)
$headElement->insertBefore( $baseElement, $headElement->firstChild );

редактировать 2
Небольшое предупреждение, хотя. Я что-то упустил.

$url = curl_getinfo( $ch, CURLINFO_EFFECTIVE_URL );

... может эффективно возвращать URL, например:

http://example.com/some/path/to/a/file.html

Я не уверен, как браузеры обрабатывают имена файлов в тегах base. Я предполагаю, что они извлекают путь к каталогу. Но не уверен насчет этого.

Но кроме этого возможного предостережения, в большинстве случаев вам, вероятно, нужно иметь только доменное имя последнего перенаправленного URL, которое будет использоваться в базовом теге.

По крайней мере, это верно для разрешения абсолютных URI, таких как

/css/some.css
/js/some.js
/some/file.html

Для разрешения относительных URI, таких как:

css/some.css
js/some.js
some/file.html

... возможно, вы также захотите извлечь часть каталога из URL:

http://example.com/some/path/to/a/

Итак, после того, как он немного подумает, вероятно, не так уж и легко объяснить все возможные сценарии. Помните об этом.

...