我构建了一个简单的网络抓取工具,它在<body>
之后回显了网页的内容。它做得很好,唯一的问题是它没有跟随页面上的链接转到递归抓取的其他页面。
在输出中,我只看到手动提供的页面内容以启动抓取工具,并且没有迹象表明它正在跟踪链接。
如何让它跟随链接,抓取这些页面并回显其内容?
以下是代码:
<?php
error_reporting( E_ERROR );
define( "CRAWL_LIMIT_PER_DOMAIN", 50 );
$domains = array();
$urls = array();
function crawl( $url )
{
global $domains, $urls;
$parse = parse_url( $url );
$domains[ $parse['host'] ]++;
$urls[] = $url;
$content = file_get_contents( $url );
if ( $content === FALSE ){
return;
}
$content = stristr($content, "<body>");
preg_match_all( '/http:\/\/[^ "\']+/', $content, $matches );
// do something with content.
echo strip_tags($content);
foreach( $matches[0] as $crawled_url ) {
$parse = parse_url( $crawled_url );
if ( count( $domains[ $parse['host'] ] ) < CRAWL_LIMIT_PER_DOMAIN && !in_array( $crawled_url, $urls ) ) {
sleep( 1 );
crawl( $crawled_url );
}
}
}
crawl('http://the-irf.com/hello/hello6.html');
?>
更新:我假设正则表达式有问题(/ http:// [^“\'] + /)。如何实现跟随所有href的正则表达式所有锚点是否以
开头http://
http:/www.
www.
https://
https://www.
或其他任何东西(例如像index.html这样的绝对文件路径)? 还是有更好的方法来做正则表达式吗?
答案 0 :(得分:1)
你应该(作为我们的意思)首先决定你实际在做什么。
当您在问题中概述时,您正在对HTTP协议的URL模式进行文本搜索。常见的正则表达式通常还包括https:
URI方案:
~https?://\S*~
直到第一个白色空间,这就是一切。这通常用于检测字符串中更宽范围的HTTP URL。如果您需要更高级的内容,请参阅Stackover Q&amp; A,了解如何点击文本链接:
这仍然无法解决所有抓取工具问题。有两个原因:
因此,仅仅进行文本分析是不够的。您还需要解析HTML。这意味着您需要获取基本URI并针对它解析文档中的每个其他URI,以获取该文档中所有绝对链接的列表。
您可以在以下白皮书中找到:
对于PHP,可以使用的两个最稳定的组件是:
DOMDocument
- 用于解析XML和HTML文档的PHP扩展。在这里,您正在寻找自然地解析HTML文档。Net_Url2
- 用于处理URL的PEAR扩展,包括符合RFC3986的参考解析(与之前版本的差异,你可以放心地忽略,标准是非常稳定的,因为PHP库是非常狭窄的两个小错误并且具体案例仍然开放但有补丁)。