【问题标题】:How do I ignore file types in a web crawler?如何忽略网络爬虫中的文件类型?
【发布时间】:2012-01-17 00:28:09
【问题描述】:

我正在编写一个网络爬虫,并希望忽略链接到二进制文件的 URL:

$exclude = %w(flv swf png jpg gif asx zip rar tar 7z gz jar js css dtd xsd ico raw mp3 mp4 wav wmv ape aac ac3 wma aiff mpg mpeg avi mov ogg mkv mka asx asf mp2 m1v m3u f4v pdf doc xls ppt pps bin exe rss xml)

如何根据这些结尾之一检查 URI?

@url = URI.parse(url)

如果不包含上述任何后缀,则应设置。

【问题讨论】:

    标签: ruby web-crawler


    【解决方案1】:

    使用 URI#path:

    unless URI.parse(url).path =~ /\.(\w+)$/ && $exclude.include?($1)
      puts "downloading #{url}..."
    end
    

    【讨论】:

      【解决方案2】:

      Ruby 缺少 Perl 拥有的一个非常有用的模块,称为 Regexp::Assemble。 Ruby 的 Regexp::Union 远不及它。下面是如何使用 Regexp::Assemble 及其结果:

      use Regexp::Assemble;
      
      my @extensions = sort qw(flv swf png jpg gif asx zip rar tar 7z gz jar js css dtd xsd ico raw mp3 mp4 wav wmv ape aac ac3 wma aiff mpg mpeg avi mov ogg mkv mka asx asf mp2 m1v m3u f4v pdf doc xls ppt pps bin exe rss xml);
      
      my $ra = Regexp::Assemble->new;
      $ra->add(@extensions);
      
      print $ra->re, "\n";
      

      哪些输出:

      (?-xism:(?:m(?:p(?:[234]|e?g)|[1o]v|k[av]|3u)|a(?:s[fx]|iff|ac|c3|pe|vi)|p(?:p[st]|df|ng)|r(?:a[rw]|ss)|w(?:m[av]|av)|x(?:ls|ml|sd)|j(?:ar|pg|s)|d(?:oc|td)|g(?:if|z)|f[4l]v|bin|css|exe|ico|ogg|swf|tar|zip|7z))
      

      Perl 支持 s 标志而 Ruby 不支持,因此需要从 ?-xism 中取出,并且我们要忽略字符大小写,因此需要移动 i,从而导致 ?i-xm .

      将其作为正则表达式插入到 Ruby 脚本中:

      REGEX = /(?i-xm:(?:m(?:p(?:[234]|e?g)|[1o]v|k[av]|3u)|a(?:s[fx]|iff|ac|c3|pe|vi)|p(?:p[st]|df|ng)|r(?:a[rw]|ss)|w(?:m[av]|av)|x(?:ls|ml|sd)|j(?:ar|pg|s)|d(?:oc|td)|g(?:if|z)|f[4l]v|bin|css|exe|ico|ogg|swf|tar|zip|7z))/
      
      @url = URI.parse(url)
      
      puts @url.path[REGEX]
      
      uri = URI.parse('http://foo.com/bar.jpg')
      uri.path        # => "/bar.jpg"
      uri.path[REGEX] # => "jpg"
      

      有关在 Ruby 中使用 Regexp::Assemble 的更多信息,请参阅“Is there an efficient way to perform hundreds of text substitutions in Ruby?”。

      【讨论】:

        【解决方案3】:

        您可以使用正则表达式或split 去掉 URL 的文件扩展名(我在这里展示了后者,但要注意这也会匹配一些格式错误的 URL,例如 http://foo.exe),然后使用 Array#include?检查成员资格:

        @url = URI.parse(url) unless $exclude.include?(url.split('.').last)
        

        【讨论】:

          猜你喜欢
          • 2012-01-13
          • 2011-10-17
          • 2011-02-04
          • 1970-01-01
          • 2018-07-19
          • 1970-01-01
          • 2012-01-14
          • 1970-01-01
          相关资源
          最近更新 更多