论坛首页 编程语言技术论坛

爬虫源码公开之一 -- wenwen.rake

浏览 8453 次
该帖已经被评为隐藏帖
作者 正文
   发表时间:2011-06-01   最后修改:2011-06-01
wenwen.rake

# == Synopsis
#
# wenwen rake all in one.
#
# == Author
# fujun
# 2011.05.08
#
# == Copyright
# Copyright (c) 2010 id86 Inc.
# All rights reserved.
#
# Usage: rake wenwen:***

WENWEN_PATH = File.join(Rails.root.to_s, 'lib', 'spider', 'wenwen')

namespace :wenwen do

  desc "list spider."
  task :list_spider => [:environment] do
    require File.join(WENWEN_PATH, 'list_spider')
    Wenwen::ListSpider.new().run
  end

  desc "detail spider."
  task :detail_spider => [:environment] do
    require File.join(WENWEN_PATH, 'detail_spider')
    Wenwen::DetailSpider.new().run
  end

end
   发表时间:2011-06-01   最后修改:2011-06-01
【Wenwen::ListSpider】的作用是通过一系列的关键字,找到

http://wenwen.soso.com上与你给出的关键字相匹配的文章列表。

soso每一页,默认返回10条结果,目前还没有找到手动指定每页返回结果条数的参数,咱们就一页一页的翻吧。

有的网站是可以通过参数指定每页返回结果的条数。

曾经遇到过一个网站,他能指定条数,并且没有限制,哈哈。导致一个请求数以万计的结果就全列出来了,太给力了。

soso这个搜索结果页,

比如:http://wenwen.soso.com/z/Search.e?sp=Sruby&w=ruby
这是搜索与关键字“ruby”相关的结果,第一条是soso百科的,无视掉。

soso的搜索结果页,里面有这么一个机制,如果你搜索的关键字有soso百科,他就会把soso百科列在第一条,也就是第一页会有11条结果。

【Wenwen::DetailSpider】的作用是用采回来的有效文章id去取相应的内容,取出相应的问题和答案,取出时间,然后结果自己写的discuz增加用户工具,将问题和答案、时间与随机的用户相关联起来。
0 请登录后投票
   发表时间:2011-06-01   最后修改:2011-06-01
再来解读一下soso的search与筛选功能:
以 http://wenwen.soso.com/z/Search.e?sp=Sruby 为例

http://wenwen.soso.com/z/Search.e?  这一堆是search功能的入口
sp=Sruby    sp参数是你要搜索的关键字,但前面加了一个“s”,这个倒是没有想明白,他为什么要这么整。手动指定你要搜索的关键字,还请URI.encode(key_word)一下,不然。。。

st参数: st=1 待解决; st=6 高悬赏; st=7 零回答
sti参数:sti=4 一天内; sti=2 一周内; sti=1 一月内

这次写爬虫,因为是第一次全爬,所以就没有只用到了st参数,sti没有用到。感觉他上面的问题也不是很多。

后面增量爬取的话,就需要指定sti了,可以每天一爬,指定sti为一天内的新问答
0 请登录后投票
   发表时间:2011-06-01  
数据库方面:

数据库名:z_id86
表名:log_wenwen_list

当时取这个名字的时候没多想,之前这数据库就一张表log_add_user 用来记录ruby的用户添加日志,所以也就随便取了这个名字了。

use z_id86;

DROP TABLE IF EXISTS `log_wenwen_list`;
CREATE TABLE `log_wenwen_list` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `keyword` varchar(100) NOT NULL DEFAULT '',
  `created_at` datetime NOT NULL,
  `updated_at` datetime NOT NULL,
  PRIMARY KEY  (`id`)
) ENGINE=InnoDB;

以 "http://wenwen.soso.com/z/Search.e?sp=Sruby" 为例
第一页是:

“Ruby 搜搜百科” -- http://baike.soso.com/ShowLemma.e?sp=l58776 --这个对我没用,直接无视掉
“Ruby和Java有什么关系么? - 精华知识” -- http://wenwen.soso.com/z/q185733709.htm
“Ruby和java” -- http://wenwen.soso.com/z/q238993261.htm
... ...


规律自然就出来了

id -- 用来保存结果页中  "http://wenwen.soso.com/z/q185733709.htm"。字母“q”后面的那一长串数字,这个也是soso的id。

keyword -- 用来将你输入的关键字进行归类,比如:"javascript什么", "javascript怎么", "javascript表单"这一类比较火的关键字,当他的结果集远远大于500的时候,soso就不会全部将结果都列出来。怎么办?只有不断地细化你的关键字,但这些细化出来的关键字,都将会归到"javascript"这个key_word下面,这样才能保证这些文章都将被发布在
"http://www.id86.com/forum-36-1.html"。这个 "js" 版块下面。

当初写这个爬虫的时候,本应该多一个步骤判断抽出来的文章标题subject是否含有你搜索用的关键字,然后再决定是否保存这个id,这样可以大大减少不相关文章的数量,要让人工去审核,这是绝不可能的。

因为soso的sphinx是用的content去build结果集的。最多500条记录,一页10条,也就是最多只有50页,这肯定是出于性能考虑的。

一来呢,如果全结果集sphinx的话,他build的时候会比较长,最主要的还是去search的时候,需要消耗大量的时间去抽这些匹配到的结果。特别是像js css html这一类关键字,那结果集是相当的庞大。

在搜索像"ruby"这种不是很火的关键字的时候,你会发现,他的结果集只有233项,并且从15页开始,标题里就已经不含"ruby"这个关键字了,那内容更是与我们想要的"ruby"差之甚远了。所以保存这个id之前应该对subject进行一下判断。
0 请登录后投票
   发表时间:2011-06-01  
之前写的时候,并没有在保存id之前就进行判断,而是在第二个爬虫请求具体某个问答页面的时候再判断的,这不科学,很浪费时间。
0 请登录后投票
   发表时间:2011-06-01  
【Wenwen::ListSpider】

【Wenwen::DetailSpider】

【Discuz::Tool】

这三个模块,还是分别用新帖子讲吧。内容太多了。
0 请登录后投票
   发表时间:2011-06-01  
这个主题里代码只有一个Rakefile,我被雷到了。

想开源可以放到github上去,然后写readme和wiki
0 请登录后投票
   发表时间:2011-06-01  
可以的话  可以告诉一下主要用到那些插件,比如抓取插件,HTML解析插件等
0 请登录后投票
   发表时间:2011-06-01  
这种渣文 还没被隐藏吗?
0 请登录后投票
   发表时间:2011-06-01  
cxh116 写道
可以的话  可以告诉一下主要用到那些插件,比如抓取插件,HTML解析插件等


gem 'rails', '~> 3.0.7'
gem 'rake', '~> 0.8.7'
gem 'json'
gem 'mysql'
gem 'mechanize'
gem 'nokogiri'
gem 'will_paginate', '~> 3.0.pre2'

我整个应用的gem就这么多了哈。
0 请登录后投票
论坛首页 编程语言技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics