用ruby写的web抓取小工具
最近由于学习使用linux下的C开发,需要查询Linux C函数参考,就经常上http://man.chinaunix.net/develop/c&c++/linux_c/default.htm查看,描述得比较详细而且还有例子。
网上还有许多各种技术的网页格式的参考材料都非常强大,可惜很多时候都没有网。于是就想写个脚本可以把文档下载,像android开发者文档一样弄到本地来,用起来就方便多了,要是用CHM工具打成chm格式就更好了。
于是就动手用ruby写了这么个脚本,把网页读取下来,保存到本地,同时下载网页中的样式、JS文件以及图片等文件,并替换相应的链接,尽量保持网页的效果。整个程序大约300行,尝试地抓取了几个网站都挺好,保留了样式、超链接甚至部分的JS。除此之外,它还能限制下载文件的类型和大小,可以……
当然,bug还很多,而且网页的HTML内容过于灵活和复杂,很多东西搞下来可能就面目全非了,真正要写一个好的parser果然是相当复杂- -!
下面是代码的注释,完整文件可在此下载。
#定义一个模块,打印日志
module Log
def Log.i(msg)
print "[INFO]#{msg}\n"
end
def Log.e(msg)
print "[ERROR]#{msg}\n"
end
end
#定义一个类,用于封装加入到队列中的url,包含了url的链接深度和待保存的文件名的信息
class UrlObj
attr_accessor :url,:depth,:save_name
def initialize(url,depth,save_name)
@url=url
@save_name=save_name
@depth=depth
end
def info#解析得到url中的信息
return @info if @info
begin
@info=URI.parse(@url)
return @info
rescue Exception=>e
Log.e e
return nil
end
end
def domain#获取url中的域名
if @domain
return @domain
elsif !info
Log.e("#{@url}'s host is nil")
return nil
elsif !info.host
Log.e("#{@url}'s host is nil")
return nil
else
return info.host[/\w+\.\w+$/]
end
end
end
接下来是最主要的一类WebSnatcher:
class WebSnatcher
THREAD_SLEEP_TIME=0.5#定义常量,线程睡眠时间
HTTP_RETRY_TIMES=3#设置打开链接的重试次数
#初始化类变量和各种设置参数
def initialize(opt={})
@url_to_download=[]#待下载的url容器
@url_to_download_count=0#待下载的url数量
相关文档:
照例可以先看端程序
class Person
def initialize( name,age=18 )
@name = name
@age = age
@motherland = "China"
end
def talk
puts "my name is "+@name+", age is "+@age.to_s
&n ......
1. ruby已成为1.87
2. 必须先安装安装光盘里的新的xcode,在"optional"目录里
3. 可能需要重新安装macport
http://trac.macports.org/wiki/Migration
4. 或者升级macport
http://weblog.rubyonrails.org/2009/8/30/upgrading-to-snow-leopard
$ sudo port selfupdate
$ sudo port sync
$ sudo port upgrade --force insta ......
原文连接: http://hi.baidu.com/%B7%CF%B2%C5%CB%FB%B8%E7/blog/item/09c19411244152daf7039ec4.html
通过命令行查看ruby版本信息:
ruby -v
命令行运行程序:
方法1.
ruby -e 'print "hello ruby"'
-e 表示将后面的一行作为ruby程序
print 是ruby的一个内置函数
方法2.交互编译环境
irb (命令行输入后, ......
#一、模块定义及引用,模块就是一段代码,里面有一些方法放一起。
#定义模块用module...end 。模块与类非常相似,但是:
#A) 模块不可以有实例对象;
#B) 模块不可以有子类。
include Math
puts sqrt(91);
module Me
def sqrt(a)
puts a*a;
return a*a;
end
PI=3.1415926 ......
To get it done is not easy. I spent a whole day to figure out the various compatibility issues along the way out.
Now there still might be potential issues, but it works by my rough test.
Step 1: Install Apache Cassandra
You may know that the Ruby gem cassandra will do it for you.
  ......