【问题标题】:Suggestions for avoiding duplicate products from scraping避免重复产品刮擦的建议
【发布时间】:2011-09-19 22:33:05
【问题描述】:

我编写了一个非常基本的爬虫,它从网站上抓取产品信息以放入数据库。

除了某些网站似乎对页面的多个部分有不同的 URL 之外,一切都很好。例如,产品 url 可能是:

http://www.example.com/product?id=52

那么,它可能有另一个 URL 用于不同的部分,例如 cmets 等:

http://www.example.com/product?id=52&revpage=1

我的抓取工具将此视为一个不同的 URL。我发现了一些网站,其中一种产品有数百个不同的 URL。我已经添加了逻辑来忽略 url 中的哈希后的任何内容以避免锚点,但我想知道是否有人有任何建议来避免这个问题?可能有一个我看不到的简单解决方案。

目前它减慢了抓取/抓取过程,其中一个网站可能只有 100 个产品,它添加了数千个 URL。

我考虑过忽略查询字符串,甚至是查询字符串的某些部分,但产品 ID 通常位于查询字符串中,所以我想不出办法,没有为每个站点的 URL 结构编写异常

【问题讨论】:

  • 您可以将您的爬虫配置为停止在任何以产品 URL 开头的 URL 中进行爬取。在您的示例中,一旦您在 http://www.example.com/product?id=52 找到产品,请不要访问以该网址开头的任何网址。这行得通吗?
  • 嗯,是的,我认为这有一些可能性,但我仍然需要先确定这一点,然后让爬虫知道。但是,我确实已经有一个网站“个人资料”,所以肯定有潜力
  • 我认为您不需要先识别任何东西。假设你从一个索引页面开始,下一层到产品描述页面,你不需要提前配置任何东西。一旦您的爬虫找到产品,它就会将信息存储在您的数据库中并保存 url 以与它找到的新 url 进行比较。请参阅下面的答案。

标签: php mysql web-crawler unique


【解决方案1】:

详细说明我的评论...

您可以包含以下代码

$producturl //is the url where you first found a product to scrape
$nexturl //is the next url you plan to crawl
if (strpos($nexturl, $producturl) === false) {
    crawl
}
loop back to the next url...

我猜你是按顺序爬行...意思是你找到一个页面并爬行到该页面的所有链接...然后你返回一级并重复...如果你没有按顺序爬行,您可以存储找到产品的所有页面,并使用它来检查您计划抓取的新页面是否以您已经抓取的 url 开头。如果是,则不抓取新页面。

我希望这会有所帮助。祝你好运!

【讨论】:

    【解决方案2】:

    您可以使用数据库并在 id 或名称上设置唯一约束。因此,如果您的爬虫尝试再次添加此数据,则会引发异常。 最简单的唯一约束是主键。

    编辑 url 参数解决方案:

    如果您在从 url 获取正确参数时遇到问题,也许从 facebook api 截取的内容可能会有所帮助。

    protected function getCurrentUrl($noQuerys = false) {
      $protocol = isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on'
        ? 'https://'
        : 'http://';
      $currentUrl = $protocol . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
      $parts = parse_url($currentUrl); // http://de.php.net/manual/en/function.parse-url.php
    
      // drop known fb params
      $query = '';
      if (!empty($parts['query'])) {
        $params = array();
        parse_str($parts['query'], $params);
        foreach(self::$DROP_QUERY_PARAMS as $key) { // self::$DROP_QUERY_PARAMS is a list of params you dont want to have in your url
          unset($params[$key]);
        }
        if (!empty($params)) {
          $query = '?' . http_build_query($params, null, '&');
        }
      }
    
      // use port if non default
      $port =
        isset($parts['port']) &&
        (($protocol === 'http://' && $parts['port'] !== 80) ||
         ($protocol === 'https://' && $parts['port'] !== 443))
        ? ':' . $parts['port'] : '';
    
    
      // rebuild
      if ($noQuerys) {
          // return URL without parameters aka querys
          return $protocol . $parts['host'] . $port . $parts['path'];
      } else {
          // return full URL
          return $protocol . $parts['host'] . $port . $parts['path'] . $query;
      }
    

    【讨论】:

    • 好吧,url 字段有一个独特的约束,但是,问题是我的示例中的两个网址 是唯一的
    • 使用id作为唯一约束不是更好吗?然后您可以识别您已经搜索过的产品吗?或者,如果您对产品使用多个站点,则应该使用复合主键(witch 是唯一约束)。
    猜你喜欢
    • 2017-01-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-24
    • 2020-08-11
    相关资源
    最近更新 更多