1

我正在创建一个类来打开网页并存储页面上所有出站链接的 href 值。由于某种原因,它适用于前 3 个然后变得更奇怪。下面是我的代码:

class Crawler {
var $url;

function construct($url) {
    $this->url = 'http://'.$url;
    $this->crawl();
}

function crawl() {
    $str = file_get_contents($this->url);
    $start = 0;
    for($i=0; $i<10; $i++) {
        $beg = strpos($str, '<a href="http://',$start)+16;
        $end = strpos($str,'"',$beg);
        $diff = $end - $beg;
        $links[$i] = substr($str,$beg, $diff);
        $start = $start + $beg;
    }
    print_r($links);
}
}

$crawler = new Crawler;
$crawler->construct('www.yahoo.com');

暂时忽略 for 循环我知道这只会返回前 10 个并且不会执行整个文档。但是,如果您运行此代码,前 3 个可以正常工作,但所有其他值都是 UBLIC。任何人都可以帮忙吗?谢谢

4

2 回答 2

2

代替:

$start = $start + $beg;

尝试:

$start = $beg;

这可能就是您只看到前三场比赛的原因。

此外,您需要插入不是的$beg支票FALSE

for($i=0; $i<10; $i++) {
    $beg = strpos($str, '<a href="http://',$start)+16;
    if ($beg === FALSE)
        break;
    //...

但是请注意,您确实应该使用DOMDocument给定标签名称(a此处)来查找文档中的所有标签。特别是,因为这是可能不是有效 XHTML 的 HTML,您应该考虑使用该loadHTML方法。

于 2010-12-22T16:21:51.743 回答
1

我认为你的逻辑有问题:

您使用 $start 标记开始查找 href 的位置,但结果$beg仍将是完整字符串的索引。因此,当您$start通过添加进行更新时,$beg您会获得较高的价值。你应该尝试$start = $beg + 1而不是$start = $start + $beg

于 2010-12-22T16:21:55.907 回答