正好这周在用ruby重写以前用php写的新闻采集程序,就顺手做一个小小的实例罢.简单了些,希望能对新接触ruby的朋友有些微帮助.
基本流程:
- 从新浪博客首页取得当前被推荐的博客列表,写入数据库
- 从数据库内读取未被采集的博客列表,依次采集
- 重复执行以上两步
开始之前的准备:
- 建立rails工作环境;
- 建立两个Model
$ ruby script/generate model resource
$ ruby script/generate model artikel
-
建立数据表
create_table :resources do |t|
t.column :title, :string
t.column :url, :string
t.column :clawed, :integer,:limit=>1
end
create_table :artikels do |t|
t.column :title, :string
t.column :url, :string
t.column :author, :string
t.column :uid, :string
t.column :body, :text
t.column :views, :integer
t.column :created_at, :datetime
end
采集:
现在进入正题
我们需要新建一个model
$ ruby script/generate mail claw
#之所以用mail model,因为这个实例一开始是写来收pop3邮件的,这个不重要.
编辑app/models/claw.rb
require 'open-uri' #打开远程文件需要载入open-uri
读取目标地址
def self.getitemlist
siteurl = open('http://blog.sina.com.cn/main/')
xhtml = siteurl.read
……
end
分析链接,分析页面内所有类如<a href="http://blog.sina.com.cn/u/46eacfc9010006hl" title="" target="_blank">中国当代作家的自卑情节</a>的字串,
并分别取得标题中国当代作家的自卑情节和目标地址46eacfc9010006hl
xhtml.gsub(/<a href=\"http:\/\/blog.sina.com.cn\/u\/(\w{16})\"(?:[^>]+)>(.+?)<\/a>/){|m|
……
#Regexp.last_match[2] #中国当代作家的自卑情节
#Regexp.last_match[1] #46eacfc9010006hl
}
写入数据库
xhtml.gsub(/<a href=\"http:\/\/blog.sina.com.cn\/u\/(\w{16})\"(?:[^>]+)>(.+?)<\/a>/){|m|
if Resource.find_by_url(Regexp.last_match[1]).nil? #url重复判断
@resource = Resource.new
@resource[:title] = Regexp.last_match[2]
@resource[:url] = Regexp.last_match[1]
@resource.save
end
}
现在我们来采集具体的blog文章
def self.getcontent
while @resource=Resource.find(:first, :conditions => ["clawed = ?",nil])
xhtml = open('http://blog.sina.com.cn/u/'+@resource.url).read
……
end
end
分析采集到的内容.作为一个小演示,偷个懒,直接把目标内容剔除所有html标签
xhtml =
xhtml.sub(%r{<body.*?>(.*?)</body>}mi, '\1').gsub(/<.*?>/m, ' ').
gsub(%r{(\n\s*){2}}, "\n\n")
得到像这样的文本
中国当代作家的自卑情节- 残雪 - 新浪BLOG var THEME = '1';
var UID = '1189793737';
var AUTHOR = '残雪'; BROWSER == "ie5" ? dw(' ') : dw(' '); 残雪的BLOG http://blog.sina.com.cn/m/canxue ﹥ 复制 ﹥ 收藏本页 HOME 残雪的BLOG 我的文章分类 ■ 我的所有文章
发表文章
中国当代作家的自卑情节 2006-12-15 09:13:56 大 中 小
我认为当代文学有不有希望,同我们接受西方文化,向西方经典学习的程度是同步的。不可否认,80年代至90年代,大家都写过一些好东西。但拿到今天来看, 那种“好”是很有限的,无论是情感积累还是文化积累都很稀薄。我这里所说的文……当然竞赛的前提是承认文学有一个共同的标准,承认人性是可以相通的,作品 是可以产生共鸣的。
评论(72) ┆ 引用 ┆ 阅读(6512) ┆ 圈子
现在来分析这个文本,取出uid,author,title,正文,发表时间和阅读次数
xhtml.gsub(/\s+(.+?)- (\S+) - 新浪BLOG(?:[\s\S]+)UID = '(\d{10})'(?:[\s\S]+)AUTHOR = '(\S+)'(?:[\s\S]+)(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2})(?:\s+)大 中 小(?:\s+)([\s\S]+)(?:\s+)(?:评论)*(?:[\s\S]+)阅读\((\d{1,})\)/){|m|
@artikel = Artikel.new
@artikel[:title] = Regexp.last_match[1]
@artikel[:url] = @resource.url
@artikel[:author] = Regexp.last_match[2]
@artikel[:uid] = Regexp.last_match[3]
@artikel[:created_at] = Regexp.last_match[5]
@artikel[:body] = Regexp.last_match[6]
@artikel[:views] = Regexp.last_match[7]
if @artikel.save
puts 'item down!' if @resource.update_attribute('clawed',1) #标记已采集过的链接
end
}
流程
def self.clean
loop do
getitemlist #从首页取得列表
getcontent #依次取回文章内容
sleep (60*5) #休息5分钟
end
end
最后:
$ ruby script/runner Claw.clean
转摘自落伍,作者:muzik