如何忽略Web爬网程序中的文件类型?

我正在编写一个Web爬虫,并希望忽略链接到二进制文件的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) 

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

使用URI #path:

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

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-xm ,从而产生?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://sofzh.miximages.com/ruby/bar.jpg') uri.path # => "/bar.jpg" uri.path[REGEX] # => "jpg" 

有关使用Ruby中的Regexp :: Assemble的更多信息,请参阅“ 在Ruby中执行数百个文本替换的有效方法吗? ”。

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

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