`
bubble
  • 浏览: 148772 次
  • 性别: Icon_minigender_1
  • 来自: 辽宁
社区版块
存档分类
最新评论

用ruby写的一个网络爬虫程序

 
阅读更多
这个程序写的很简单,刚接触ruby第二天写的,主要完成的功能是到斯坦福大学的网站上去收集email地址,  ,默认是10个线程,策略是广度优先,$debug=true时开启调试信息。附件中包含代码和批处理文件。

运行命令为:
ruby Crawl.rb 2 1000 http://www-cs.stanford.edu/People
其中参数:2->max_depth, 1000->max_pages, http://www-cs.stanford.edu/People->URL
运行结果输出为文档文件emails_md[max_depth]_mp[max_pages]_[URL].txt

居然删不了帖子,那我就拿掉吧,剩着再遭隐藏,呵呵
还是贴回来吧,省着自己想找都找不到,哈哈

require 'open-uri'
require 'thread'
# run it like this :
# ruby Crawl.rb 2 1000 http://www-cs.stanford.edu/People
# regexp
$link_regexp = /href\=\"[^\"]*\"/
$email_regexp_1 = /mailto\:[^\@]*\@[^\"]*[\"]/	#mailto:xx@xxxx"
$email_regexp_2 = /[\>][^\<]*\@[^\>]*[\<]/	#>xx@xx<
$before_at = /[a-zA-Z0-9]+[_?a-zA-Z0-9]+/
$after_at = /[a-zA-Z]+[-?a-zA-Z]*\.+[a-zA-Z]+/
$email_regexp=/#{$before_at}\@#{$after_at}/	#xx@xx.xx

#ARGV 
if ARGV==nil||ARGV.length<3
	puts '-- Command --'
	puts 'ruby Crawl.rb 2 1000 http://www-cs.stanford.edu/People'
	puts 'help: 2->max_depth, 1000->max_pages, http://www-cs.stanford.edu/People->url'
	exit(0)
end
$url=ARGV[2]
$max_depth=ARGV[0].to_i
$max_pages=ARGV[1].to_i
$fname='emails_md'+String($max_depth)+'_mp'+String($max_pages)+'_'+$url.gsub(/[\/\:]/,'_')+'.txt'
$fname_links='links_md'+String($max_depth)+'_mp'+String($max_pages)+'_'+$url.gsub(/[\/\:]/,'_')+'.txt'
$thread_num=10
$debug=true

$links_stack=[]		#fifo #[[depth1,link1],[depth2,link2],[depth3,link3],...]
$links_crawled=[]	#[url1,url2,url3,...] 
$emails=[]		#[email1,email2,email3,...]

class Crawl
	def initialize url,depth
		@url=url
		while @url[-1,1]=='/'
			@url=@url.slice(0,@url.length-1) 
		end
		@depth=depth
		begin
		@html=open(@url).read
		rescue
		@html=''
		end
	end
	def get_links
		@html.scan($link_regexp) do |match| 
			u=Util.format_url(match,@url)
			if !(u==nil)&&!$links_crawled.include?(match)&&$links_stack.rassoc(match)==nil
				$links_stack.push [@depth,u]
			end
		end
	end
	def get_emails
		@html.scan($email_regexp_1) do |match| 
			match=Util.format_email(match)
			if match!=nil&&!$emails.include?(match)
				$emails.push match
				msg= match+', '+@url
				puts msg
				Util.write($fname,msg+"\r\n")
			end
		end
		@html.scan($email_regexp_2) do |match| 
			match=Util.format_email(match)
			if match!=nil&&!$emails.include?(match)
				$emails.push match
				msg= match+', '+@url
				puts msg
				Util.write($fname,msg+"\r\n")
			end
		end
	end
end

class Util
	# format url
	def Util.format_url url,f_url
		# remove 'www-'
		f_url=f_url.gsub(/www\-/, '')
		url=url[6,url.length-7]
		# exclude css & js & '#'(eg http://www-cs.stanford.edu/People/faculty#Regular%20Faculty)...
		if Util.exclude(url)==nil||url.include?('#')
			return nil
		end
		# full path
		if url[0,4]!='http'
			while url.index('/')==0
				url=url.slice(1,url.length-1) 
			end
			url=f_url+'/'+url
		end
		return url
	end
	# format email
	def Util.format_email email
		email=email.delete('>').delete('<').delete('mailto:').delete('"').strip
		if String($email_regexp.match(email))== email
			return email.downcase
		else
			return nil
		end
	end
	# write msg to file
	def Util.write fname,msg
		file=File.new(fname,'a')
		file<<msg
		file.close()
	end
	# exclude css & js...
	def Util.exclude str
		ex=['css','js','pdf','jpg']
		ex.each do |e|
			index=e.length+1
			if str.length>index && str[-index,index]=='.'+e
				return nil
			end
		end
		return str
	end
end
$count=1
0.upto($max_depth) do |i|
	if $debug
		puts '~~depth->'+String(i)
	end	
	if i==0
		c=Crawl.new($url,i+1)
		c.get_links
		c.get_emails
		$links_crawled.push [i,$url]
	end
	#breadth first 
	while $links_stack.length!=0
		if $debug
			puts '~~count->'+String($count)+',stack->'+String($links_stack.length)+',crawled->'+String($links_crawled.length)+',total->'+String($links_crawled.length+$links_stack.length)
			$count=$count+1
		end		
		#Thread.abort_on_exception = true
		threads = []
		if $links_stack.length/$thread_num>=1
			ts=$thread_num
		else 
			ts=$links_stack.length%$thread_num
		end
		ts.times { |i|
			threads << Thread.new(i) {
			Mutex.new.synchronize {
				if ($links_crawled.length+$links_stack.length)<=$max_pages&&i!=$max_depth
					link=$links_stack.shift		#fifo
					if  link[0]==i+1
						#read links & emails from pages in stack
						c=Crawl.new(link[1],i+2)
						c.get_links
						c.get_emails
						$links_crawled.push link[1]
					else 
						break
					end
				else
					#only read emails from pages in stack
					link=$links_stack.shift
					c=Crawl.new(link[1],i+2)
					c.get_emails
					$links_crawled.push link[1]
				end
			}
			}
		}
		threads.each{|t|t.join}
	end
end
分享到:
评论
7 楼 bubble 2009-12-13  
我准备把帖子删掉算了,心寒啊。
qiaoakai 写道
Very Good!!!虽然,我没看懂!!

呵呵,写的太烂是不是?
wangfsec 写道
怎么做到广度优先的?

用的队列。
hc_face 写道
我还不会用隐藏贴,但是我在学ruby,敬佩楼主的贡献精神,学习!!

多亏你不会用隐藏帖,要不又多一个,汗!
tianyuzhu 写道
原来如此,

这位大哥受到啥启发了?
6 楼 tianyuzhu 2009-12-12  
原来如此,
5 楼 hc_face 2009-12-12  
我还不会用隐藏贴,但是我在学ruby,敬佩楼主的贡献精神,学习!!
4 楼 wangfsec 2009-12-12  
怎么做到广度优先的?
3 楼 qiaoakai 2009-12-12  
Very Good!!!虽然,我没看懂!!
2 楼 bubble 2009-12-12  
呵呵,有点郁闷居然6个隐藏帖,给点面子不好吗,投个新手帖我还能接受,javaeye玩Ruby的看来都是高手啊
1 楼 wangxin0072000 2009-12-11  
$link_regexp = /href\=\"[^\"]*(\")$/  

相关推荐

    用Python写网络爬虫-35

    网络爬虫是一个自动提取网页的程序,它为搜索引擎从万维网上下载网页,是搜索引擎的重要组成部分。传统爬虫从一个或若干初始网页的URL开始,获得初始网页上的URL,在抓取网页的过程中,不断从当前页面上抽取新的URL...

    ruby写的网络蜘蛛

    在Ruby网络爬虫中,Nokogiri常用于提取网页上的数据,如HTML元素、属性值、链接等。通过使用Nokogiri,你可以使用XPath或CSS选择器来定位你需要的信息。 2. Mechanize:Mechanize库是专门针对网站交互设计的,它...

    用ruby写的采集程序.zip

    标题中的“用ruby写的采集程序”表明这是一个使用Ruby编程语言编写的网络数据采集脚本。Ruby是一种面向对象的、动态类型的编程语言,以其简洁、优雅的语法和强大的元编程能力而受到开发者喜爱。在Web开发领域,Ruby...

    不同语言实现的爬虫程序和爬虫框架.zip

    本资源“不同语言实现的爬虫程序和爬虫框架.zip”包含了一个名为"awesome-crawler-master"的开源项目,这个项目汇集了多种编程语言实现的爬虫程序和爬虫框架,旨在为开发者提供丰富的参考和学习材料。 首先,我们来...

    Ruby-RubyRetriever异步Web爬虫

    RubyRetriever是一款基于Ruby语言实现的异步Web爬虫工具,它被设计为一个既可以作为命令行程序运行,也可以作为框架供开发者自定义爬取逻辑的解决方案。这个项目的核心特性在于其异步处理能力,这使得它在抓取大量...

    网络爬虫-Python和数据分析

    网络爬虫是一种能够自动获取网页内容的程序,它在搜索引擎的运作中扮演了至关重要的角色。它从一个或多个指定的初始网页地址出发,抓取网页内容,并且不断从当前页面中提取新的链接地址,以继续下载更多页面,直到...

    网络爬虫-Python数据分析

    网络爬虫是自动提取网页信息的程序,它对大数据技术至关重要,因为数据的获取是大数据处理的首要条件。网络爬虫在搜索引擎技术中扮演着基础而关键的角色,它从互联网下载网页,为搜索引擎提供内容来源。传统爬虫的...

    用Python写网络爬虫-35页

    网络爬虫是自动提取网页的程序,为搜索引擎从万维网上下载网页,是搜索引擎的重要组成。传统爬虫从一个或若干初始网页的URL开始,获得初始网页上的URL,在抓取网页的过程中,不断从当前页面上抽取新的URL放入队列,...

    网络爬虫-Python和数据分析.pdf

    网络爬虫从一个或一组起始URL开始,获取页面并从中提取出新的URL,这个过程持续进行直到达到预定的停止条件。这种技术在多个领域都有广泛应用,如通用搜索引擎的网页收集、垂直搜索引擎的构建、科学研究中的数据收集...

    网络爬虫-python和数据分析

    为了展示如何使用Python编写一个基本的网络爬虫,下面是一个简单的示例代码: ```python import requests from bs4 import BeautifulSoup def fetch_page(url): response = requests.get(url) if response....

    网络爬虫—python和数据分析

    网络爬虫的工作原理是从一个或多个初始的URL出发,获取这些页面上的所有链接,然后再访问这些链接所指向的页面,循环往复,直到满足停止条件为止。这个过程类似于蜘蛛通过自己的网获取食物一样,因此得名“爬虫”。 ...

    网络爬虫爬取Ajax

    ### 网络爬虫爬取Ajax:利用Ruby技术实现 在现代互联网应用中,Ajax(Asynchronous JavaScript ...这种方法不仅适用于Ruby开发环境,也可以扩展到其他编程语言和技术栈中,为网络爬虫开发者提供了一种实用的解决方案。

    Ruby写的自动播报工行白银价格

    标题“Ruby写的自动播报工行白银价格”表明这是一个使用Ruby编程语言编写的程序,它的主要功能是自动获取工商银行的白银价格,并通过音频方式进行播报。在金融领域,实时的价格信息对于投资者来说至关重要,这个工具...

    zhizhu.rar_news crawler_网络爬虫 获取

    总结来说,"zhizhu.rar_news crawler_网络爬虫 获取"是一个使用JAVA编写的简单网络爬虫项目,其目的是抓取特定网站的新闻内容。通过分析和理解这个项目,可以学习到网络爬虫的基本原理和JAVA编程技巧,以及如何处理...

    基于Selenium的Python网络爬虫的实现.pdf

    Selenium作为一个强大的自动化测试工具,它可以帮助爬虫程序模拟用户的行为,绕过某些反爬机制,高效地爬取所需数据。 ### 知识点二:爬虫的流程与技术架构 爬虫程序的实现流程大致分为以下几个步骤: 1. 初始化...

Global site tag (gtag.js) - Google Analytics