利用这个周末做了个小练习,用的mechanize 抓取了人人网的一些网页。
rails各种环境都配置好以后,rails new test -d mysql创建了一个用mysql数据库的工程
然后为本项目创建一个mysql用户和一个数据库,配置项目里的database.yml数据库文件
由于初次接触mechanize,所以都是在实验的同时写的代码,关键部分的代码网上的有相关的实例,本人也是秉着练练手的目的做的,代码的直接就放在model里了,运行的时候在rails c里执行的,感觉这样比较方便,就没写task任务。刚刚开始练习,至于多线程,进程中断,遍历树广度优先和深度优先等均没考虑。
其实本不打算去人人网做实验,是冲着qq空间去的,但是mechanize在我这个目的下的缺点就暴露出来了,当然他也有他的专长。由于qq空间的页面大多是js生成的,而mechanize去抓取页面的时候不去运行js,所以导致了无法抓取有效信息,且登陆需要使用cookie才能登陆,由于目前还不清楚如何实现,mechanize适合抓取链接。
通过好友和最近访客抓取人人网的用户信息,目前还存在一个比较麻烦的问题,每访问100个用户就需要输入一次验证码,网上有人提供了一个可行方案,验证码跟cookie存在联系,通过cookie找到验证码库,这个功能没做实验。
运行前需要安装mechanize,在Gemfile中加入gem ‘mechanize’,gem install mechanize,bundle install,这样就装上了。
下面是部分代码
require'rubygems'
require'mechanize'
def self.save_user_renren
email='自己账号' #账号密码
password='密码值'
@agent=Mechanize.new
@agent.user_agent_alias='Windows Mozilla'
[email protected]('http://www.renren.com')
@agent.open_timeout=10
page.encoding='utf-8'
#填表登陆人人,登陆后的页面存放到login_page
form=page.forms.first
form.field_with(:name=>'email').value=email
form.field_with(:type=>'password').value=password
login_page=form.click_button #表单登陆方法
first_user = User.create_first_user(848764357) #创建第一个用户,我是存到了id_list表了
(1..5).each do |depth| #按深度来进行遍历
other_user(depth)
end
end
def self.other_user(depth) #目前只存储了用户的遍历深度和用户的对应网址信息的一个数字字符串
IdList.where(user_depth:depth).each do |id_user|
[email protected]("http://www.renren.com/#{id_user.renren_user_id}/profile")
user_page.links_with(:href=>/\/profile$/).each do |link|
depth=id_user.user_depth+1
User.save_user_id(link.href[22,9].to_i,depth)
end
end
end
def self.create_first_user(user_id)
IdList.create(id:1,renren_user_id:user_id,user_depth:0)
end
def self.save_user_id(user_id,depth)
current_id=IdList.find_by(renren_user_id:user_id)
IdList.create(renren_user_id:user_id,user_depth:depth)unlesscurrent_id.present?
end
由于是实验,所以只存了一个用户对应人人网的唯一标示--数字字符串和深度,由于存在每访问一百个用户后需要输入验证码,且每位用户最多只取页面显示的10到20多个好友,本人只有三个好友,所以深度到4时已有3000多,深度到5将近四五万,还是因为验证码问题,所以我只抓到2万个id
后来去分析的网页,根据id拼的路由,为用户创建了基本信息,还是因为验证码,只抓了一千个用户信息,不知是网络原因还是进程出问题,有时会卡住,还出现一些脏数据。
出现的一个报错信息Net::HTTP::Persistent::Error: too many connection resets (due to Net::ReadTimeout - Net::ReadTimeout) after 200 requests on 46030880, last used 120.489427646 seconds ago
page.save('page.html')这样就可以将抓到的网页代码存到page.html中了,若要存为日志型的,Logger.new('page.html').info(page)
页面分析及存在的各种问题,以后都做了相应实验后更新。
(本人新手,欢迎指出不足之处和改进意见)