1

我是一个 php 新手,但我很确定这将很难完成并且非常消耗服务器。但我想问一下,得到比我更聪明的用户的意见。

这是我正在尝试做的事情:

我有一个 URL 列表,实际上是一个 URL 数组。

对于每个 URL,我想计算该页面上没有 REL="nofollow" 属性的传出链接。

所以在某种程度上,恐怕我必须让 php 加载页面并使用正则表达式匹配所有链接?

如果我有 1000 个链接,这会起作用吗?

这是我的想法,将其放入代码中:

$homepage = file_get_contents('http://www.site.com/');

$homepage = htmlentities($homepage);

// Do a preg_match for http:// and count the number of appearances:
$urls = preg_match();

// Do a preg_match for rel="nofollow" and count the nr of appearances:
$nofollow = preg_match();


// Do a preg_match for the number of "domain.com" appearances so we can subtract the website's internal links:
$internal_links = preg_match();

// Substract and get the final result: 
$result = $urls - $nofollow - $internal_links;

希望你能提供帮助,如果这个想法是正确的,也许你可以帮助我处理 preg_match 函数。

4

2 回答 2

4

您可以使用 PHP 的DOMDocument类来解析 HTML 和parse_url来解析 URL:

$url = 'http://stackoverflow.com/';
$pUrl = parse_url($url);

// Load the HTML into a DOMDocument
$doc = new DOMDocument;
@$doc->loadHTMLFile($url);

// Look for all the 'a' elements
$links = $doc->getElementsByTagName('a');

$numLinks = 0;
foreach ($links as $link) {

    // Exclude if not a link or has 'nofollow'
    preg_match_all('/\S+/', strtolower($link->getAttribute('rel')), $rel);
    if (!$link->hasAttribute('href') || in_array('nofollow', $rel[0])) {
        continue;
    }

    // Exclude if internal link
    $href = $link->getAttribute('href');

    if (substr($href, 0, 2) === '//') {
        // Deal with protocol relative URLs as found on Wikipedia
        $href = $pUrl['scheme'] . ':' . $href;
    }

    $pHref = @parse_url($href);
    if (!$pHref || !isset($pHref['host']) ||
        strtolower($pHref['host']) === strtolower($pUrl['host'])
    ) {
        continue;
    }

    // Increment counter otherwise
    echo 'URL: ' . $link->getAttribute('href') . "\n";
    $numLinks++;

}

echo "Count: $numLinks\n";
于 2013-01-19T04:37:32.303 回答
2

您可以使用SimpleHTMLDOM

// Create DOM from URL or file
$html = file_get_html('http://www.site.com/');

// Find all links 
foreach($html->find('a[href][rel!=nofollow]') as $element) {
    echo $element->href . '<br>';
}

由于我不确定 SimpleHTMLDOM 是否支持:not选择器并且[rel!=nofollow] 可能只返回a具有rel属性的标签(而不是存在属性的标签),您可能必须:

foreach($html->find('a[href][!rel][rel!=nofollow]') as $element)

注意添加的[!rel]. 或者,手动而不是使用 CSS 属性选择器:

// Find all links 
foreach($html->find('a[href]') as $element) {
    if (strtolower($element->rel) != 'nofollow') {
        echo $element->href . '<br>';
    }
}
于 2013-01-19T03:48:41.153 回答