我正在开发一个项目,我想在后台搜索一个网站的内容,并从该网站获取一些有限的内容.例如,在我的页面中,我有"userid"和"password"字段,通过使用那些我将访问我的邮件并抓取我的收件箱内容并将其显示在我的页面中.
我通过单独使用javascript完成了上述操作.但是,当我单击登录按钮时,我的页面的URL(http://localhost/web/Login.html)将更改为URL(http://mail.in.com/mails/inbox.php?nomail= ......)我被刮掉了.但我在不改变我的网址的情况下废弃了细节.
绝对使用PHP Simple HTML DOM Parser.它快速,简单且超级灵活.它基本上将整个HTML页面粘贴在一个对象中,然后您可以访问该对象中的任何元素.
与官方网站的示例一样,要获取Google主页上的所有链接:
// Create DOM from URL or file $html = file_get_html('http://www.google.com/'); // Find all images foreach($html->find('img') as $element) echo $element->src . '
'; // Find all links foreach($html->find('a') as $element) echo $element->href . '
';
首先,您发出HTTP请求以获取页面内容.有几种方法可以做到这一点.
发送HTTP请求的最基本方法是使用fopen
.一个主要优点是您可以设置一次读取多少个字符,这在读取非常大的文件时非常有用.但是,这并不是最容易做到的事情,除非你正在阅读非常大的文件并担心遇到内存问题,否则不建议这样做.
$fp = fopen("http://www.4wtech.com/csp/web/Employee/Login.csp", "rb"); if (FALSE === $fp) { exit("Failed to open stream to URL"); } $result = ''; while (!feof($fp)) { $result .= fread($fp, 8192); } fclose($fp); echo $result;
最简单的方法就是使用file_get_contents
.如果与fopen或多或少相同,但您可以选择较少的选项.这里的一个主要优点是它只需要一行代码.
$result = file_get_contents('http://www.4wtech.com/csp/web/Employee/Login.csp'); echo $result;
如果您需要更多地控制将哪些标头发送到服务器,您可以结合使用套接字fopen
.
$fp = fsockopen("www.4wtech.com/csp/web/Employee/Login.csp", 80, $errno, $errstr, 30); if (!$fp) { $result = "$errstr ($errno)
\n"; } else { $result = ''; $out = "GET / HTTP/1.1\r\n"; $out .= "Host: www.4wtech.com/csp/web/Employee/Login.csp\r\n"; $out .= "Connection: Close\r\n\r\n"; fwrite($fp, $out); while (!feof($fp)) { $result .= fgets($fp, 128); } fclose($fp); } echo $result;
或者,您也可以使用流.流是类似于插座和可与两者组合使用fopen
和file_get_contents
.
$opts = array( 'http'=>array( 'method'=>"GET", 'header'=>"Accept-language: en\r\n" . "Cookie: foo=bar\r\n" ) ); $context = stream_context_create($opts); $result = file_get_contents('http://www.4wtech.com/csp/web/Employee/Login.csp', false, $context); echo result;
如果您的服务器支持cURL(通常是这样),则建议使用cURL.使用cURL的一个关键优势是它依赖于其他编程语言中常用的流行C库.它还提供了一种方便的方法来创建请求标头,并自动解析响应标头,并在出现错误时使用简单的界面.
$defaults = array( CURLOPT_URL, "http://www.4wtech.com/csp/web/Employee/Login.csp" CURLOPT_HEADER=> 0 ); $ch = curl_init(); curl_setopt_array($ch, ($options + $defaults)); if( ! $result = curl_exec($ch)) { trigger_error(curl_error($ch)); } curl_close($ch); echo $result;
或者,您可以使用许多PHP库中的一个.我不建议使用库,因为它可能是矫枉过正的.在大多数情况下,最好使用cURL编写自己的HTTP类.
PHP有一种方便的方法可以将任何HTML加载到DOMDocument
.
$pagecontent = file_get_contents('http://www.4wtech.com/csp/web/Employee/Login.csp'); $doc = new DOMDocument(); $doc->loadHTML($pagecontent); echo $doc->saveHTML();
不幸的是,PHP对HTML5的支持是有限的.如果您在尝试解析页面内容时遇到错误,请考虑使用第三方库.为此,我可以推荐Masterminds/html5-php.使用此库解析HTML文件与使用解析HTML文件非常相似DOMDocument
.
use Masterminds\HTML5; $pagecontent = file_get_contents('http://www.4wtech.com/csp/web/Employee/Login.csp'); $html5 = new HTML5(); $dom = $html5->loadHTML($html); echo $html5->saveHTML($dom);
或者,您可以使用例如.我的库PHPPowertools/DOM-Query.它使用自定义版本的Masterminds/html5-php将HTML5字符串解析为DomDocument
和symfony/DomCrawler,以便将CSS选择器转换为XPath选择器.DomDocument
即使将一个对象传递给另一个对象,它也总是使用相同的,以确保良好的性能.
namespace PowerTools; // Get file content $pagecontent = file_get_contents( 'http://www.4wtech.com/csp/web/Employee/Login.csp' ); // Define your DOMCrawler based on file string $H = new DOM_Query( $pagecontent ); // Define your DOMCrawler based on an existing DOM_Query instance $H = new DOM_Query( $H->select('body') ); // Passing a string (CSS selector) $s = $H->select( 'div.foo' ); // Passing an element object (DOM Element) $s = $H->select( $documentBody ); // Passing a DOM Query object $s = $H->select( $H->select('p + p') ); // Select the body tag $body = $H->select('body'); // Combine different classes as one selector to get all site blocks $siteblocks = $body->select('.site-header, .masthead, .site-body, .site-footer'); // Nest your methods just like you would with jQuery $siteblocks->select('button')->add('span')->addClass('icon icon-printer'); // Use a lambda function to set the text of all site blocks $siteblocks->text(function( $i, $val) { return $i . " - " . $val->attr('class'); }); // Append the following HTML to all site blocks $siteblocks->append(''); // Use a descendant selector to select the site's footer $sitefooter = $body->select('.site-footer > .site-center'); // Set some attributes for the site's footer $sitefooter->attr(array('id' => 'aweeesome', 'data-val' => 'see')); // Use a lambda function to set the attributes of all site blocks $siteblocks->attr('data-val', function( $i, $val) { return $i . " - " . $val->attr('class') . " - photo by Kelly Clark"; }); // Select the parent of the site's footer $sitefooterparent = $sitefooter->parent(); // Remove the class of all i-tags within the site's footer's parent $sitefooterparent->select('i')->removeAttr('class'); // Wrap the site's footer within two nex selectors $sitefooter->wrap('');