我正在开发一个小型的webcrawler作为一个侧面项目,基本上让它收集页面上的所有href,然后解析那些,我的问题是。
我怎样才能获得实际的页面结果?目前我正在使用以下
foreach($page->getElementsByTagName('a') as $link)
{
$compare_url = parse_url($link->getAttribute('href'));
if (@$compare_url['host'] == "")
{
$links[] = 'http://'.@$base_url['host'].'/'.$link->getAttribute('href');
}
elseif ( @$base_url['host'] == @$compare_url['host'] )
{
$links[] = $link->getAttribute('href');
}
}
正如您所看到的,这将带来jpegs,exe文件等。我只需要拾取网页,如.php,.html,.asp等。
我不确定是否有某些功能可以解决这个问题,或者是否需要从某种主列表中使用正则表达式?
由于
答案 0 :(得分:1)
由于URL字符串本身不以任何方式与其后面的资源相关联,因此您必须向Web服务器询问它们。为此,有一个名为HEAD的HTTP方法,因此您不必下载所有内容。
你可以在php中用curl实现这个:
function is_html($url) {
function curl_head($url) {
$curl = curl_init($url);
curl_setopt($curl, CURLOPT_NOBODY, true);
curl_setopt($curl, CURLOPT_HEADER, true);
curl_setopt($curl, CURLOPT_MAXREDIRS, 5);
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true );
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_HTTP_VERSION , CURL_HTTP_VERSION_1_1);
$content = curl_exec($curl);
curl_close($curl);
// redirected heads just pile up one after another
$parts = explode("\r\n\r\n", trim($content));
// return only the last one
return end($parts);
}
$header = curl_head('http://github.com');
// look for the content-type part of the header response
return preg_match('/content-type\s*:\s*text\/html/i', $header);
}
var_dump(is_html('http://github.com'));
此版本仅接受text/html
响应,不会检查响应是否为404或其他错误(但重定向最多为5次跳转)。您可以调整regexp或在curl响应中添加一些错误处理,或者通过匹配标题字符串的第一行。
注意: Web服务器将在这些URL后面运行脚本以便为您提供响应。注意不要使用探测过载主机,或者抓取“删除”或“取消订阅”类型的链接。
答案 1 :(得分:0)
检查页面是否有效(html,php ...扩展名使用此功能:
function check($url){
$extensions=array("php","html"); //Add extensions here
foreach($extensions as $ext){
if(substr($url,-(strlen($ext)+1))==".".$ext){
return 1;
}
}
return 0;
}
foreach($page->getElementsByTagName('a') as $link) {
$compare_url = parse_url($link->getAttribute('href'));
if (@$compare_url['host'] == "") { if(check($link->getAttribute('href'))){ $links[] = 'http://'.@$base_url['host'].'/'.$link->getAttribute('href');} }
elseif ( @$base_url['host'] == @$compare_url['host'] ) {
if(check($link->getAttribute('href'))){ $links[] = $link->getAttribute('href'); }
}
答案 2 :(得分:0)
考虑使用preg_match
检查链接的类型(应用程序,图片,html文件),并考虑结果决定该怎么做。
另一个选项(简单)是使用explode
并找到.
之后的最后一个网址字符串(扩展名)
例如:
//If the URL will has any one of the following extensions , ignore them.
$forbid_ext = array('jpg','gif','exe');
foreach($page->getElementsByTagName('a') as $link) {
$compare_url = parse_url($link->getAttribute('href'));
if (@$compare_url['host'] == "")
{
if(check_link_type($link->getAttribute('href')))
$links[] = 'http://'.@$base_url['host'].'/'.$link->getAttribute('href');
}
elseif ( @$base_url['host'] == @$compare_url['host'] )
{
if(check_link_type($link->getAttribute('href')))
$links[] = $link->getAttribute('href');
}
}
function check_link_type($url)
{
global $forbid_ext;
$ext = end(explode("." , $url));
if(in_array($ext , $forbid_ext))
return false;
return true;
}
更新(而不是检查'禁止'扩展程序,让我们寻找好的扩展程序)
$good_ext = array('html','php','asp');
function check_link_type($url)
{
global $good_ext;
$ext = end(explode("." , $url));
if($ext == "" || !in_array($ext , $good_ext))
return true;
return false;
}