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

利用hpricot抓取baidu的图片

浏览 14100 次
精华帖 (8) :: 良好帖 (0) :: 新手帖 (2) :: 隐藏帖 (0)
作者 正文
   发表时间:2008-09-28  
最近忙里抽闲,研究了一下hpricot,感觉真是不错,我用它很轻松地实现了百度图片的批量下载。

如:在百度图片搜索中输入“泰晤士河”,想把查找到的所在大图片都拉到本地电脑上面,还要一个个去点小图片,进入大图显示页面,才能将图片保存起来,真是不方便。

现在我通过hpricot来搞定这个。
目标URL就是我百度图片搜索中输入“泰晤士河”产生的URL:
http://image.baidu.com/i?tn=baiduimage&ct=201326592&cl=2&lm=-1&pv=&word=%CC%A9%CE%EE%CA%BF%BA%D3&z=0
我现在通过hpricot找出查询结果中的所有显示大图的页面链接,然后再在大图中分析URL,找出大图img的src,进而利用open-uri进行文件读写,从而把图片拉下来。

现在在看一下代码吧,看,代码量这么少,Ruby就是方便和人性化。
require 'rubygems'  
require 'hpricot'
require 'open-uri'

#取得查询结果页面的所有指向大图页面的链接(目前取了第一页)
def get_link_list								
	target_url = "http://image.baidu.com/i?tn=baiduimage&word=%CC%A9%CE%EE%CA%BF%BA%D3&z=0&lm=-1&ct=201326592&cl=2"
	doc = open(target_url) { |f| Hpricot(f) }
	link_list = Array.new
	doc.search("div#imgid/dl/dd/div/a").each do |r|
		link_list << "http://image.baidu.com"+r.attributes["href"]
	end	
 	link_list
end

#将大图页面中的大图片下载到本地电脑
def down_load(url)
	doc = open(url) { |f| Hpricot(f) }
	#     /div/table/tbody/tr/td
	doc.search("a[@target='_top']/") do |r|
		file_url = r.attributes["src"]
		puts file_url + "\n"
		file_name = file_url[file_url.rindex("/")+1, file_url.size]
		open(file_url) do |data|
		new_image = File.new(file_name, "w")
		new_image.puts data.read
		new_image.close
		end
	end
end

#将所有的图片都下载到本地电脑中
def down_load_all_images
	get_link_list.each do |url|
		down_load(url)
	end
end

#执行方法
down_load_all_images


初次使用,感觉hpricot解析HTML真是方便,就是那么几下子就搞定了,并且感觉速度不错,以后如果要用到爬虫方面,用这个没错。

另外,感觉使用Ruby写代码,真是舒服啊。
   发表时间:2008-09-28  
听说ruby不错  简洁  想看下
正好这有个例子   看来 RUBY用途不少呢
0 请登录后投票
   发表时间:2008-09-28  
也许你不需要用hpricot那么底层的东西,推荐http://mechanize.rubyforge.org/mechanize/,使用的也是hpricot
0 请登录后投票
   发表时间:2008-09-28  
楼主,你的代码写得太难看了,按照你那个需要,不要10行代码就可以搞定了。你写的实在太不ruby style了,呵呵,还是不打击楼主了。

8 请登录后投票
   发表时间:2008-09-28  
robbin 写道
楼主,你的代码写得太难看了,按照你那个需要,不要10行代码就可以搞定了。你写的实在太不ruby style了,呵呵,还是不打击楼主了。


同意,ruby配合命令行才是王道。
0 请登录后投票
   发表时间:2008-09-28  
花花公子 写道
robbin 写道
楼主,你的代码写得太难看了,按照你那个需要,不要10行代码就可以搞定了。你写的实在太不ruby style了,呵呵,还是不打击楼主了。


同意,ruby配合命令行才是王道。


的确,如果用unix shell配合wget这个命令工具,也就一行代码。
0 请登录后投票
   发表时间:2008-09-30  
robbin 写道
花花公子 写道
robbin 写道
楼主,你的代码写得太难看了,按照你那个需要,不要10行代码就可以搞定了。你写的实在太不ruby style了,呵呵,还是不打击楼主了。


同意,ruby配合命令行才是王道。


的确,如果用unix shell配合wget这个命令工具,也就一行代码。


高手可否写出这一行代码~~
0 请登录后投票
   发表时间:2008-10-01  
robbin 写道
楼主,你的代码写得太难看了,按照你那个需要,不要10行代码就可以搞定了。你写的实在太不ruby style了,呵呵,还是不打击楼主了。


"10行代码就可以搞定了,结合命令行更少".能给出具体的方法吗?
0 请登录后投票
   发表时间:2008-10-01  
使用正则表达式的例子:

require 'open-uri'
target_url = "http://image.baidu.com/i?tn=baiduimage&word=%CC%A9%CE%EE%CA%BF%BA%D3&z=0&lm=-1&ct=201326592&cl=2"
open(target_url).read.scan(/<a name='pn\d+' href="(.*?)"/){|link| 
  img_url = open("http://image.baidu.com/#{link}").read[/_top"><img src="(.*?)"/, 1]
  open(img_url[/\/([^\/]*?)$/, 1], "wb").write(open(img_url).read)
}


如果配合Robbin说的wget,硬要在一行里面搞定也可以:
open(target_url).read.scan(/<a name='pn\d+' href="(.*?)"/){|link| `wget #{open("http://image.baidu.com/#{link}").read[/_top"><img src="(.*?)"/, 1]}`}
2 请登录后投票
   发表时间:2009-05-04  
下张图片那里要十行咯。10行之内就可以搞定
0 请登录后投票
论坛首页 编程语言技术版

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