我想使用PHP来抓取我们拥有的大约有6或7千个href链接的文档。我们需要的是链接另一端的内容,这意味着PHP必须遵循每个链接并获取链接的内容。可以这样做吗?
由于
答案 0 :(得分:1)
当然,只需使用像file_get_contents(http://nl.php.net/file_get_contents)这样的函数获取起始网址的内容,使用正则表达式在此页面的内容中查找网址,抓取这些网址的内容等。
Regexp将类似于:
$regexUrl = "/(http|https|ftp|ftps)\:\/\/[a-zA-Z0-9\-\.]+\.[a-zA-Z]{2,3}(\/\S*)?/";
答案 1 :(得分:0)
我只有一个SQL表,其中包含我找到的所有链接,以及它们是否已被解析。
然后我使用Simple HTML DOM来解析最旧的添加页面,虽然因为它有大页面(500kb + html)的内存耗尽,我使用正则表达式来实现其中一些*。对于每个链接,我发现我将它添加到SQL数据库中需要解析,以及我找到它的时间。
SQL数据库可以防止数据因错误而丢失,因为我有10万多个要解析的链接,我会在很长一段时间内完成。
我不确定,但你检查了file_get_contents()的useragent吗?如果它不是您的页面并且您发出了1000个请求,则可能需要更改用户代理,方法是编写自己的HTTP下载器或使用库中的一个(我使用Zend Framework中的一个)但是cURL等工作得很好。如果您使用自定义用户代理,则允许管理员查看日志以查看有关您的机器人的信息。 (我倾向于说明我爬行的原因以及我的联系方式。)
*我使用的正则表达式是:
'/<a[^>]+href="([^"]+)"[^"]*>/is'
更好的解决方案(来自Gumbo)可能是:
'/<a\s+(?:[^"'>]+|"[^"]*"|'[^']*')*href=("[^"]+"|'[^']+'|[^<>\s]+)/i'
答案 2 :(得分:0)
收获链接后,您可以使用curl或file_get_contents(在安全的环境中,file_get_contents不应允许遍历http协议)
答案 3 :(得分:0)
PHP Snoopy库有许多内置函数可以完全满足您的需求。
http://sourceforge.net/projects/snoopy/
您可以使用Snoopy下载页面本身,然后它还有另一个功能来提取该页面上的所有URL。它甚至会将链接更正为完整的URI(即它们不仅仅与页面所在的域/目录相关)。
答案 4 :(得分:0)
您可以尝试以下操作。有关详细信息,请参阅this thread
<?php
//set_time_limit (0);
function crawl_page($url, $depth = 5){
$seen = array();
if(($depth == 0) or (in_array($url, $seen))){
return;
}
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
$result = curl_exec ($ch);
curl_close ($ch);
if( $result ){
$stripped_file = strip_tags($result, "<a>");
preg_match_all("/<a[\s]+[^>]*?href[\s]?=[\s\"\']+"."(.*?)[\"\']+.*?>"."([^<]+|.*?)?<\/a>/", $stripped_file, $matches, PREG_SET_ORDER );
foreach($matches as $match){
$href = $match[1];
if (0 !== strpos($href, 'http')) {
$path = '/' . ltrim($href, '/');
if (extension_loaded('http')) {
$href = http_build_url($url, array('path' => $path));
} else {
$parts = parse_url($url);
$href = $parts['scheme'] . '://';
if (isset($parts['user']) && isset($parts['pass'])) {
$href .= $parts['user'] . ':' . $parts['pass'] . '@';
}
$href .= $parts['host'];
if (isset($parts['port'])) {
$href .= ':' . $parts['port'];
}
$href .= $path;
}
}
crawl_page($href, $depth - 1);
}
}
echo "Crawled {$href}";
}
crawl_page("http://www.sitename.com/",3);
?>
答案 5 :(得分:-1)
我建议您将带有6000个URL的HTML文档,解析出来并循环显示您已获得的列表。在循环中,使用file_get_contents获取当前URL的内容(为此,在服务器上启用file_get_contents时,实际上不需要cURL),再次解析包含的URL,依此类推。
看起来像这样:
<?php
function getUrls($url) {
$doc = file_get_contents($url);
$pattern = "/(http|https|ftp|ftps)\:\/\/[a-zA-Z0-9\-\.]+\.[a-zA-Z]{2,3}(\/\S*)?/";
preg_match_all($pattern, $doc, $urls);
return $urls;
}
$urls = getUrls("your_6k_file.html");
foreach($urls as $url) {
$moreUrls = getUrls($url);
//do something with moreUrls
}
?>