DOM文档,编辑元素

时间:2011-10-19 05:57:59

标签: php html domdocument

所以,我想做的是制作一个脚本,它会自动将我的登录信息(我将在我的数据库中)添加到我想要的任何形式。

要做到这一点,我从网站上获取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,所以我无法正确加载它,因为它使用我的网址

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

我的问题是如何才能完成这项工作? 如何编辑链接以包含网站网址? 由于这是我第一次使用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 个答案:

答案 0 :(得分:1)

我认为最简单的方法是将base标记注入href属性设置为最后一个有效网址的基本网址(最终由cURL提取的网址)可能的重定向)。可以使用以下命令使用cURL检索最后一个有效URL:

$url = curl_getinfo( $ch, CURLINFO_EFFECTIVE_URL );

我已经解释了如何使用DOMDocument in this answer设置基本标记。它还说明了已有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 );

...可以有效地返回一个网址:

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

我不确定浏览器如何处理base标记中的文件名。我假设他们提取目录路径。但不确定这一点。

但除了可能的警告之外,在大多数情况下,您可能只想拥有最后一个重定向网址的域名,以便在基本标记中使用。

至少这对于解决绝对的uri来说是正确的,例如

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

用于解决相关的uri,例如:

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

...你可能也想提取网址的目录部分:

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

因此,在考虑了一点之后,考虑所有可能的情景可能并非如此微不足道。请注意这一点。