设计网络爬虫


72

我遇到了一个采访问题“如果您正在设计Web搜寻器,如何避免陷入无限循环?”,而我正试图回答这个问题。

这一切是如何从头开始的。假设Google从一些中心页面开始说,其中有数百个(首先如何找到这些中心页面是一个不同的子问题)。当Google跟踪页面中的链接等时,它是否会继续创建哈希表以确保它不遵循先前访问的页面。

如果当我们拥有URL缩短器等功能时,如果同一页面上有2个名称(URL)怎么办?

我以Google为例。尽管Google不会泄漏其网络爬虫算法和页面排名等的工作原理,但是有什么猜测吗?

Answers:


83

如果您想获得详细的答案,请参阅本文的第3.8节,其中描述了现代刮板的URL测试:

在提取链接的过程中,任何Web爬网程序都会遇到指向同一文档的多个链接。为避免多次下载和处理文档,必须在每个提取的链接上执行URL可见测试,然后才能将其添加到URL边界。(另一种设计是,当从边界删除URL时,执行URL可见测试,但是这种方法会导致更大的边界。)

为了执行可查看URL的测试,我们将Mercator看到的所有URL以规范形式存储在一个称为URL集的大表中。再次,太多条目无法容纳它们,因此像文档指纹集一样,URL集主要存储在磁盘上。

为了节省空间,我们不在URL集中存储每个URL的文本表示形式,而是存储固定大小的校验和。与呈现给内容可见测试的文档指纹集的指纹不同,针对该URL集测试的URL流具有非常重要的局部性。为了减少对备份磁盘文件的操作次数,因此,我们保留了流行URL的内存中缓存。这种缓存的直觉是指向某些URL的链接非常普遍,因此将流行的URL缓存在内存中将导致较高的内存命中率。

实际上,使用2 ^ 18个条目的内存高速缓存和类似LRU的时钟替换策略,我们在内存高速缓存中的总命中率达到66.2%,而在内存表上的命中率达到9.5%。最近添加的网址,净命中率为75.7%。此外,在流行URL的缓存和最近添加的URL的表中丢失的请求中,有24.3%的请求中,大约1 = 3在我们的随机访问文件实现中的缓冲区上产生了命中,该文件也位于用户空间中。所有这些缓冲的最终结果是,我们对URL集执行的每个成员资格测试平均产生0.16个搜索和0.17个读内核调用(其中一部分是从内核的文件系统缓冲区中提供的)。因此,每个URL集成员资格测试所引发的内核调用的数量是文档指纹集上成员资格测试的六分之一。

基本上,它们使用散列函数对所有URL进行散列,该函数可确保每个URL都有唯一的散列,并且由于URL的局部性,查找URL变得非常容易。Google甚至将其哈希功能开源:CityHash

警告!
他们可能还在谈论机器人陷阱!!!漫游器陷阱是页面的一部分,该页面不断生成具有唯一URL的新链接,通过跟踪该页面提供的链接,您实际上将陷入“无限循环”。这并非完全是一个循环,因为循环将是访问相同URL的结果,但这是无限的URL链,您应避免爬网。

201212月13更新-世界应该终结的第二天:)

根据Fr0zenFyr的评论:如果使用AOPIC算法选择页面,则避免无限循环类型的陷阱很容易。这是AOPIC工作原理的摘要:

  1. 获取一组N个种子页面。
  2. 向每个页面分配X信用额度,以便在开始搜寻之前每个页面都有X / N信用额(即相等信用额度)。
  3. 选择一个页面P,其中P具有最高信用额度(或者如果所有页面具有相同信用额度,则爬网随机页面)。
  4. 抓取页面P(假设P被抓取时有100个积分)。
  5. 提取页面P中的所有链接(假设有10个)。
  6. 将P的信用设置为0。
  7. 收取10%的“税”并将其分配到Lambda页面。
  8. 在P页上从P的原始信用中分配的每个链接分配等量的信用-税金:因此(100(P信用)-10(10%税))/ 10(链接)=每个链接9个信用。
  9. 从第3步开始重复。

由于Lambda页面不断收取税款,因此最终它将是信用额度最高的页面,我们将不得不对其进行“爬网”。我用引号说“爬网”,因为我们实际上并不向Lambda页面发出HTTP请求,我们只是获得其信用并将其平均分配给数据库中的所有页面。

由于漫游器陷阱只会给内部链接提供积分,而很少从外部获得积分,因此它们会不断(从税收中)泄漏积分到Lambda页面。Lambda页面会将这些信用额平均分配到数据库中的所有页面,并且在每个周期中,bot陷阱页面将失去越来越多的信用额,直到其信用额非常少以至于几乎再也不会被爬网。好的页面不会发生这种情况,因为它们通常会从其他页面上的反向链接中获得收益。这也会导致页面排名动态变化,您会注意到,每当您对数据库进行快照时,都按照页面拥有的信用额度对页面进行排序,那么很可能会根据其真实页面排名对页面进行大致排序

这只能避免无限循环类型的自动程序陷阱,但是您还应注意许多其他自动程序陷阱,并且也有一些方法可以解决它们。


很好的解释。关于循环(上面已回答)和机器人陷阱(仍在寻找一种解决问题的好方法),我也有同样的问题。如果SO允许,我会为CityHash额外提供+1。干杯;)
Fr0zenFyr 2012年

@ Fr0zenFyr您不必担心无限循环类型的漫游器陷阱,尤其是当您使用AOPIC算法选择要爬网的URL时。我将更详细地更新我的答案。
基里尔

@ Fr0zenFyr因此,避免机器人陷阱的最好方法是有礼貌地进行爬网,否则,您将不得不研究所有可能被困的方法并解决它们。也就是说,您基本上必须实现浏览器,使用代理并通过切换用户代理(根据浏览器使用情况统计信息)来模仿多个浏览
Kiril 2012年

我当前的模型完全遵循robots.txt,no-follow等,并且不进行主动抓取。感谢您对帖子的更新,我将在AOPIC上尝试您的建议。顺便说一句,玛雅历法审判日是2012
Fr0zenFyr 2012年

1
@raju不会在每个周期都发生,只有在您“爬取” lambda时才会发生。“爬行” lambda不会经常发生,您可以异步进行。它不需要实时发生,而只需要最终发生即可。
基里尔

7

虽然这里的每个人都已经建议了如何创建您的网络搜寻器,但是这里是Google如何对页面进行排名。

Google根据回调链接的数量(其他网站上指向特定网站/页面的链接数量)对每个页面进行排名。这称为相关性得分。这是基于以下事实:如果页面上有许多其他页面链接到该页面,则该页面可能是重要页面。

每个站点/页面都被视为图中的一个节点。指向其他页面的链接是有向边的。顶点的度数定义为进入边缘的数量。具有较高输入边缘数的节点排名较高。

确定页面等级的方法如下。假设页面Pj具有Lj链接。如果这些链接之一是指向页面Pi,则Pj将其重要性的1 / Lj传递给Pi。然后,Pi的重要性排名是链接到它的页面所做的所有贡献的总和。因此,如果我们表示通过Bi链接到Pi的页面集,则我们具有以下公式:

Importance(Pi)= sum( Importance(Pj)/Lj ) for all links from Pi to Bi

等级放置在称为超链接矩阵的矩阵中:H [i,j]

如果存在从Pi到Bi的链接,则此矩阵中的一行为0或1 / Lj。该矩阵的另一个特性是,如果我们将一列中的所有行相加,则得到1。

现在,我们需要将此矩阵乘以一个特征向量I(特征值1),以使其:

I = H*I

现在我们开始迭代:I H,I I H,I I I^ h .... I ^ K *小时,直到解收敛。也就是说,在步骤k和k + 1中,矩阵中的数字几乎相同。

现在,I向量中剩下的就是每一页的重要性。

有关简单的课堂作业示例,请参见http://www.math.cornell.edu/~mec/Winter2009/RalucaRemus/Lecture3/lecture3.html

至于解决面试问题中的重复问题,请在整个页面上做一个校验和,并使用该校验或bash或bash作为您在地图中的关键字来跟踪访问的页面。


1
如果页面吐出动态内容,则校验和可能会不同。
edocetirwi

@edocetirwi好点,我想您可能需要寻找其他方法或以某种有意义的方式将其与URL结合起来
Adrian

哦,所以你只是集成在hyperlink matrix具有尺寸every-webpage-on-the-internetX every-webpage-on-the-internet。简单?!?如何做到这一点(鉴于其非常稀疏的矩阵)?
CpILL

@CpILL您迟到了7年,但是有一些聪明的方法可以在不爆炸的情况下将大型矩阵相乘;如果您需要生产就绪的解决方案,我愿意接受付款
Adrian

@Adrian我确定你是...但是我注意到它主要是Stackoverflow上的开发人员,我们喜欢自己做,这就是为什么我们在这里!:D
CpILL

1

取决于他们的问题的意图。如果他们只是想避免来回跟踪相同的链接,则对URL进行散列就足够了。

那么,具有成千上万个导致相同内容的URL的内容呢?就像QueryString参数一样,它不会影响任何东西,但是可以具有无限数量的迭代。我想您也可以对页面的内容进行哈希处理,并比较URL的内容以查看它们是否类似于捕获由多个URL标识的内容。例如,参见@Lirik的帖子中提到的Bot Traps。


这使我想到了另一个问题。我们如何散列页面的全部内容。这样的页面至少说2个寻呼机。什么样的哈希函数能够将2个寻呼机哈希为一个值?通常这样的哈希输出的大小是多少?
xyz

0

您必须要有某种哈希表来存储结果,您只需要在加载每个页面之前对其进行检查即可。


0

这里的问题不是要爬网重复的URL,这是通过使用从url获得的哈希值的索引来解决的。问题是要检索“重复的内容”。“ Crawler Trap”的每个网址都不同(年,日,SessionID ...)。

没有“完美”的解决方案...但是您可以使用以下一些策略:

•在网站内部保留网址的级别。对于从页面获取网址的每个线索,请提高级别。它将像一棵树。您可以在特定级别停止抓取,例如10(我认为Google使用此级别)。

•您可以尝试创建一种HASH,可以将其比较以查找相似的文档,因为您无法与数据库中的每个文档进行比较。有来自谷歌的SimHash,但我找不到任何实现。然后,我创建了自己的。我的哈希计算html代码中的低频和高频字符,并生成20bytes的哈希,并将其与AVLTree中最近爬行的页面的少量缓存进行比较,并使用具有一定容差(约2)的NearNeighbors搜索。您不能在此哈希中使用任何对字符位置的引用。在“识别”陷阱之后,您可以记录重复内容的url模式,并开始忽略具有该内容的页面。

•与google一样,您可以为每个网站创建排名,并在一个网站中“信任”更多。


0

搜寻器保留一个URL池,其中包含要搜寻的所有URL。为了避免“无限循环”,基本思想是在添加到池之前检查每个URL的存在。

但是,当系统扩展到一定级别时,这并不容易实现。天真的方法是将所有URL都保留在哈希集中,并检查每个新URL的存在。如果有太多的URL不能容纳到内存中,则无法使用此功能。

这里有几种解决方案。例如,我们应该将所有URL保留在磁盘中,而不是将所有URL存储到内存中。为了节省空间,应使用URL哈希而不是原始URL。还需要注意的是,我们应该保留URL的规范形式,而不是原始形式。因此,如果通过bit.ly之类的服务将URL缩短,则最好获得最终URL。为了加快检查过程,可以构建一个缓存层。或者,您可以将其视为分布式缓存系统,这是一个单独的主题。

构建网络爬网程序”一文对此问题进行了详细分析。



0

网络搜寻器是一种计算机程序,用于从给定的网站URL收集/搜寻以下关键值(HREF链接,图像链接,元数据等)。它的设计非常聪明,可以跟踪从上一个URL已获取的不同HREF链接,因此,Crawler可以从一个网站跳转到其他网站。通常,它称为Web蜘蛛或Web Bot。这种机制始终充当Web搜索引擎的骨干。

请从我的技术博客中找到源代码-http: //www.algonuts.info/how-to-built-a-simple-web-crawler-in-php.html

<?php
class webCrawler
{
    public $siteURL;
    public $error;

    function __construct()
    {
        $this->siteURL = "";
        $this->error = "";
    }

    function parser()   
    {
        global $hrefTag,$hrefTagCountStart,$hrefTagCountFinal,$hrefTagLengthStart,$hrefTagLengthFinal,$hrefTagPointer;
        global $imgTag,$imgTagCountStart,$imgTagCountFinal,$imgTagLengthStart,$imgTagLengthFinal,$imgTagPointer;
        global $Url_Extensions,$Document_Extensions,$Image_Extensions,$crawlOptions;

        $dotCount = 0;
        $slashCount = 0;
        $singleSlashCount = 0;
        $doubleSlashCount = 0;
        $parentDirectoryCount = 0;

        $linkBuffer = array();

        if(($url = trim($this->siteURL)) != "")
        {
            $crawlURL = rtrim($url,"/");
            if(($directoryURL = dirname($crawlURL)) == "http:")
            {   $directoryURL = $crawlURL;  }
            $urlParser = preg_split("/\//",$crawlURL);

            //-- Curl Start --
            $curlObject = curl_init($crawlURL);
            curl_setopt_array($curlObject,$crawlOptions);
            $webPageContent = curl_exec($curlObject);
            $errorNumber = curl_errno($curlObject);
            curl_close($curlObject);
            //-- Curl End --

            if($errorNumber == 0)
            {
                $webPageCounter = 0;
                $webPageLength = strlen($webPageContent);
                while($webPageCounter < $webPageLength)
                {
                    $character = $webPageContent[$webPageCounter];
                    if($character == "")
                    {   
                        $webPageCounter++;  
                        continue;
                    }
                    $character = strtolower($character);
                    //-- Href Filter Start --
                    if($hrefTagPointer[$hrefTagLengthStart] == $character)
                    {
                        $hrefTagLengthStart++;
                        if($hrefTagLengthStart == $hrefTagLengthFinal)
                        {
                            $hrefTagCountStart++;
                            if($hrefTagCountStart == $hrefTagCountFinal)
                            {
                                if($hrefURL != "")
                                {
                                    if($parentDirectoryCount >= 1 || $singleSlashCount >= 1 || $doubleSlashCount >= 1)
                                    {
                                        if($doubleSlashCount >= 1)
                                        {   $hrefURL = "http://".$hrefURL;  }
                                        else if($parentDirectoryCount >= 1)
                                        {
                                            $tempData = 0;
                                            $tempString = "";
                                            $tempTotal = count($urlParser) - $parentDirectoryCount;
                                            while($tempData < $tempTotal)
                                            {
                                                $tempString .= $urlParser[$tempData]."/";
                                                $tempData++;
                                            }
                                            $hrefURL = $tempString."".$hrefURL;
                                        }
                                        else if($singleSlashCount >= 1)
                                        {   $hrefURL = $urlParser[0]."/".$urlParser[1]."/".$urlParser[2]."/".$hrefURL;  }
                                    }
                                    $host = "";
                                    $hrefURL = urldecode($hrefURL);
                                    $hrefURL = rtrim($hrefURL,"/");
                                    if(filter_var($hrefURL,FILTER_VALIDATE_URL) == true)
                                    {   
                                        $dump = parse_url($hrefURL);
                                        if(isset($dump["host"]))
                                        {   $host = trim(strtolower($dump["host"]));    }
                                    }
                                    else
                                    {
                                        $hrefURL = $directoryURL."/".$hrefURL;
                                        if(filter_var($hrefURL,FILTER_VALIDATE_URL) == true)
                                        {   
                                            $dump = parse_url($hrefURL);    
                                            if(isset($dump["host"]))
                                            {   $host = trim(strtolower($dump["host"]));    }
                                        }
                                    }
                                    if($host != "")
                                    {
                                        $extension = pathinfo($hrefURL,PATHINFO_EXTENSION);
                                        if($extension != "")
                                        {
                                            $tempBuffer ="";
                                            $extensionlength = strlen($extension);
                                            for($tempData = 0; $tempData < $extensionlength; $tempData++)
                                            {
                                                if($extension[$tempData] != "?")
                                                {   
                                                    $tempBuffer = $tempBuffer.$extension[$tempData];
                                                    continue;
                                                }
                                                else
                                                {
                                                    $extension = trim($tempBuffer);
                                                    break;
                                                }
                                            }
                                            if(in_array($extension,$Url_Extensions))
                                            {   $type = "domain";   }
                                            else if(in_array($extension,$Image_Extensions))
                                            {   $type = "image";    }
                                            else if(in_array($extension,$Document_Extensions))
                                            {   $type = "document"; }
                                            else
                                            {   $type = "unknown";  }
                                        }
                                        else
                                        {   $type = "domain";   }

                                        if($hrefURL != "")
                                        {
                                            if($type == "domain" && !in_array($hrefURL,$this->linkBuffer["domain"]))
                                            {   $this->linkBuffer["domain"][] = $hrefURL;   }
                                            if($type == "image" && !in_array($hrefURL,$this->linkBuffer["image"]))
                                            {   $this->linkBuffer["image"][] = $hrefURL;    }
                                            if($type == "document" && !in_array($hrefURL,$this->linkBuffer["document"]))
                                            {   $this->linkBuffer["document"][] = $hrefURL; }
                                            if($type == "unknown" && !in_array($hrefURL,$this->linkBuffer["unknown"]))
                                            {   $this->linkBuffer["unknown"][] = $hrefURL;  }
                                        }
                                    }
                                }
                                $hrefTagCountStart = 0;
                            }
                            if($hrefTagCountStart == 3)
                            {
                                $hrefURL = "";
                                $dotCount = 0;
                                $slashCount = 0;
                                $singleSlashCount = 0;
                                $doubleSlashCount = 0;
                                $parentDirectoryCount = 0;
                                $webPageCounter++;
                                while($webPageCounter < $webPageLength)
                                {
                                    $character = $webPageContent[$webPageCounter];
                                    if($character == "")
                                    {   
                                        $webPageCounter++;  
                                        continue;
                                    }
                                    if($character == "\"" || $character == "'")
                                    {
                                        $webPageCounter++;
                                        while($webPageCounter < $webPageLength)
                                        {
                                            $character = $webPageContent[$webPageCounter];
                                            if($character == "")
                                            {   
                                                $webPageCounter++;  
                                                continue;
                                            }
                                            if($character == "\"" || $character == "'" || $character == "#")
                                            {   
                                                $webPageCounter--;  
                                                break;  
                                            }
                                            else if($hrefURL != "")
                                            {   $hrefURL .= $character; }
                                            else if($character == "." || $character == "/")
                                            {
                                                if($character == ".")
                                                {
                                                    $dotCount++;
                                                    $slashCount = 0;
                                                }
                                                else if($character == "/")
                                                {
                                                    $slashCount++;
                                                    if($dotCount == 2 && $slashCount == 1)
                                                    $parentDirectoryCount++;
                                                    else if($dotCount == 0 && $slashCount == 1)
                                                    $singleSlashCount++;
                                                    else if($dotCount == 0 && $slashCount == 2)
                                                    $doubleSlashCount++;
                                                    $dotCount = 0;
                                                }
                                            }
                                            else
                                            {   $hrefURL .= $character; }
                                            $webPageCounter++;
                                        }
                                        break;
                                    }
                                    $webPageCounter++;
                                }
                            }
                            $hrefTagLengthStart = 0;
                            $hrefTagLengthFinal = strlen($hrefTag[$hrefTagCountStart]);
                            $hrefTagPointer =& $hrefTag[$hrefTagCountStart];
                        }
                    }
                    else
                    {   $hrefTagLengthStart = 0;    }
                    //-- Href Filter End --
                    //-- Image Filter Start --
                    if($imgTagPointer[$imgTagLengthStart] == $character)
                    {
                        $imgTagLengthStart++;
                        if($imgTagLengthStart == $imgTagLengthFinal)
                        {
                            $imgTagCountStart++;
                            if($imgTagCountStart == $imgTagCountFinal)
                            {
                                if($imgURL != "")
                                {
                                    if($parentDirectoryCount >= 1 || $singleSlashCount >= 1 || $doubleSlashCount >= 1)
                                    {
                                        if($doubleSlashCount >= 1)
                                        {   $imgURL = "http://".$imgURL;    }
                                        else if($parentDirectoryCount >= 1)
                                        {
                                            $tempData = 0;
                                            $tempString = "";
                                            $tempTotal = count($urlParser) - $parentDirectoryCount;
                                            while($tempData < $tempTotal)
                                            {
                                                $tempString .= $urlParser[$tempData]."/";
                                                $tempData++;
                                            }
                                            $imgURL = $tempString."".$imgURL;
                                        }
                                        else if($singleSlashCount >= 1)
                                        {   $imgURL = $urlParser[0]."/".$urlParser[1]."/".$urlParser[2]."/".$imgURL;    }
                                    }
                                    $host = "";
                                    $imgURL = urldecode($imgURL);
                                    $imgURL = rtrim($imgURL,"/");
                                    if(filter_var($imgURL,FILTER_VALIDATE_URL) == true)
                                    {   
                                        $dump = parse_url($imgURL); 
                                        $host = trim(strtolower($dump["host"]));
                                    }
                                    else
                                    {
                                        $imgURL = $directoryURL."/".$imgURL;
                                        if(filter_var($imgURL,FILTER_VALIDATE_URL) == true)
                                        {   
                                            $dump = parse_url($imgURL); 
                                            $host = trim(strtolower($dump["host"]));
                                        }   
                                    }
                                    if($host != "")
                                    {
                                        $extension = pathinfo($imgURL,PATHINFO_EXTENSION);
                                        if($extension != "")
                                        {
                                            $tempBuffer ="";
                                            $extensionlength = strlen($extension);
                                            for($tempData = 0; $tempData < $extensionlength; $tempData++)
                                            {
                                                if($extension[$tempData] != "?")
                                                {   
                                                    $tempBuffer = $tempBuffer.$extension[$tempData];
                                                    continue;
                                                }
                                                else
                                                {
                                                    $extension = trim($tempBuffer);
                                                    break;
                                                }
                                            }
                                            if(in_array($extension,$Url_Extensions))
                                            {   $type = "domain";   }
                                            else if(in_array($extension,$Image_Extensions))
                                            {   $type = "image";    }
                                            else if(in_array($extension,$Document_Extensions))
                                            {   $type = "document"; }
                                            else
                                            {   $type = "unknown";  }
                                        }
                                        else
                                        {   $type = "domain";   }

                                        if($imgURL != "")
                                        {
                                            if($type == "domain" && !in_array($imgURL,$this->linkBuffer["domain"]))
                                            {   $this->linkBuffer["domain"][] = $imgURL;    }
                                            if($type == "image" && !in_array($imgURL,$this->linkBuffer["image"]))
                                            {   $this->linkBuffer["image"][] = $imgURL; }
                                            if($type == "document" && !in_array($imgURL,$this->linkBuffer["document"]))
                                            {   $this->linkBuffer["document"][] = $imgURL;  }
                                            if($type == "unknown" && !in_array($imgURL,$this->linkBuffer["unknown"]))
                                            {   $this->linkBuffer["unknown"][] = $imgURL;   }
                                        }
                                    }
                                }
                                $imgTagCountStart = 0;
                            }
                            if($imgTagCountStart == 3)
                            {
                                $imgURL = "";
                                $dotCount = 0;
                                $slashCount = 0;
                                $singleSlashCount = 0;
                                $doubleSlashCount = 0;
                                $parentDirectoryCount = 0;
                                $webPageCounter++;
                                while($webPageCounter < $webPageLength)
                                {
                                    $character = $webPageContent[$webPageCounter];
                                    if($character == "")
                                    {   
                                        $webPageCounter++;  
                                        continue;
                                    }
                                    if($character == "\"" || $character == "'")
                                    {
                                        $webPageCounter++;
                                        while($webPageCounter < $webPageLength)
                                        {
                                            $character = $webPageContent[$webPageCounter];
                                            if($character == "")
                                            {   
                                                $webPageCounter++;  
                                                continue;
                                            }
                                            if($character == "\"" || $character == "'" || $character == "#")
                                            {   
                                                $webPageCounter--;  
                                                break;  
                                            }
                                            else if($imgURL != "")
                                            {   $imgURL .= $character;  }
                                            else if($character == "." || $character == "/")
                                            {
                                                if($character == ".")
                                                {
                                                    $dotCount++;
                                                    $slashCount = 0;
                                                }
                                                else if($character == "/")
                                                {
                                                    $slashCount++;
                                                    if($dotCount == 2 && $slashCount == 1)
                                                    $parentDirectoryCount++;
                                                    else if($dotCount == 0 && $slashCount == 1)
                                                    $singleSlashCount++;
                                                    else if($dotCount == 0 && $slashCount == 2)
                                                    $doubleSlashCount++;
                                                    $dotCount = 0;
                                                }
                                            }
                                            else
                                            {   $imgURL .= $character;  }
                                            $webPageCounter++;
                                        }
                                        break;
                                    }
                                    $webPageCounter++;
                                }
                            }
                            $imgTagLengthStart = 0;
                            $imgTagLengthFinal = strlen($imgTag[$imgTagCountStart]);
                            $imgTagPointer =& $imgTag[$imgTagCountStart];
                        }
                    }
                    else
                    {   $imgTagLengthStart = 0; }
                    //-- Image Filter End --
                    $webPageCounter++;
                }
            }
            else
            {   $this->error = "Unable to proceed, permission denied";  }
        }
        else
        {   $this->error = "Please enter url";  }

        if($this->error != "")
        {   $this->linkBuffer["error"] = $this->error;  }

        return $this->linkBuffer;
    }   
}
?>

1
这并不能真正回答以下问题:“如果您正在设计Web搜寻器,那么如何避免陷入无限循环?”请改进您的回答。
Brian Tompsett-汤莱恩19'May

嗨,大脑先生,谢谢您的评论,实际上我们需要为该类创建一个实例,然后我们可以申请使用。
喀特屈恩·穆尔西

-1

好的,网络基本上是有向图,因此您可以从URL构造图,然后在标记访问的节点时进行BFS或DFS遍历,因此您不会两次访问同一页面。


3
但是,首先如何构造图形?如果我们不希望有重复的节点,即我们只希望一个URL节点,那么您又需要一种在构造图形本身的同时检测并丢弃重复项的方法。–
xyz

@learnerforever hmmm是的,是的。。。老实说,我只编写了一个简单的搜寻器,仅处理约100个链接,因此实际上进入每个页面并不是一个大问题。但是,是的,当您将其应用于整个网络时,我可以看到出现的问题。Lirik的论文似乎值得,但是……
Pepe

-1

这是一个网络爬虫示例。可用于收集用于MAC欺骗的mac地址。

#!/usr/bin/env python

import sys
import os
import urlparse
import urllib
from bs4 import BeautifulSoup

def mac_addr_str(f_data):
global fptr
global mac_list
word_array = f_data.split(" ")

    for word in word_array:
        if len(word) == 17 and ':' in word[2] and ':' in word[5] and ':' in word[8] and ':' in word[11] and ':' in word[14]:
            if word not in mac_list:
                mac_list.append(word)
                fptr.writelines(word +"\n")
                print word



url = "http://stackoverflow.com/questions/tagged/mac-address"

url_list = [url]
visited = [url]
pwd = os.getcwd();
pwd = pwd + "/internet_mac.txt";

fptr = open(pwd, "a")
mac_list = []

while len(url_list) > 0:
    try:
        htmltext = urllib.urlopen(url_list[0]).read()
    except:
        url_list[0]
    mac_addr_str(htmltext)
    soup = BeautifulSoup(htmltext)
    url_list.pop(0)
    for tag in soup.findAll('a',href=True):
        tag['href'] = urlparse.urljoin(url,tag['href'])
        if url in tag['href'] and tag['href'] not in visited:
            url_list.append(tag['href'])
            visited.append(tag['href'])

更改网址以抓取更多网站……祝您好运

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.