python爬图片

转载 2015年11月19日 22:27:21

参考了别人的代码。给代码添加了多线程和Queue的结合应用。

[python] view plaincopy
  1. #!/usr/bin/env python  
  2. # -*- coding:utf-8 -*-  
  3.   
  4. ''''' 
  5. Created on 2013-3-21 
  6.  
  7. @author: naughty 
  8. '''  
  9. # author: wklken  
  10.   
  11. from sgmllib import SGMLParser  
  12. import os  
  13. import urllib  
  14. import urllib2  
  15. import urlparse  
  16. from Queue import Queue  
  17. from threading import Thread  
  18.   
  19. save_path = '/home/zoer'  
  20. passUrls = set()  
  21.   
  22. qimg = Queue()  
  23. class URLLister(SGMLParser):  
  24.     def reset(self):  
  25.         SGMLParser.reset(self)  
  26.         self.urls = []  
  27.         self.imgs = []  
  28.     def start_a(self, attrs):  
  29.         href = [ v for k, v in attrs if k == "href" and v.startswith("http")]  
  30.         if href:  
  31.             self.urls.extend(href)  
  32.     def start_img(self, attrs):  
  33.         src = [ v for k, v in attrs if k == "src" and v.startswith("http") ]  
  34.         if src:  
  35.             self.imgs.extend(src)  
  36.   
  37. def get_url_of_page(url, if_img=False):  
  38.     ''''' 
  39.     获取一个页面上的所有链接。 
  40.     if_img:如果为true,则获取的是页面上的所有图片的链接 
  41.     '''  
  42.     urls = []  
  43.     try:  
  44.         f = urllib2.urlopen(url, timeout=3).read()  
  45.         url_listen = URLLister()  
  46.         url_listen.feed(f)  
  47.         if if_img:  
  48.             urls.extend(url_listen.imgs)  
  49.         else:  
  50.             urls.extend(url_listen.urls)  
  51.     except urllib2.URLError, e:  
  52.         print e  
  53.     return urls  
  54.   
  55. def get_page_html(begin_url, depth, main_site_domain):  
  56.     ''''' 
  57.     递归处理页面 
  58.     '''  
  59.     if depth <= 0:  
  60.         return  
  61.     print 'handle ' + begin_url  
  62.     passUrls.add(begin_url)  
  63.     #===========================================================================  
  64.     # 读取本页面上的图片  
  65.     #===========================================================================  
  66.     urls = get_url_of_page(begin_url, True)  
  67.     #===========================================================================  
  68.     # 添加图片到queue  
  69.     #===========================================================================  
  70.     for murl in urls:  
  71.         firstindex = murl.find('?')  
  72.         if firstindex != -1:  
  73.             print firstindex  
  74.             murl = murl[:firstindex]  
  75.         print 'add img url:' + murl  
  76.         qimg.put(murl)  
  77.     #===============================================================================  
  78.     # 读取本页面上的链接  
  79.     #===============================================================================  
  80.     urls = get_url_of_page(begin_url)  
  81.     if urls:  
  82.         for murl in urls:  
  83.             if not murl in passUrls:  
  84.                 get_page_html(murl, depth - 1, main_site_domain)  
  85.   
  86. class DPThread(Thread):  
  87.     ''''' 
  88.     下载线程 
  89.     '''  
  90.     def run3(self):  
  91.         while True:  
  92.             filename = qimg.get()  
  93.             filename = filename.split("/")[-1]  
  94.             #dist = os.path.join(save_path, filename)  
  95.             dist = save_path + '/' + filename  
  96.             print dist  
  97.             print 'try connecting ' + filename  
  98.             if filename.endswith('jpg'or filename.endswith('png'or filename.endswith('gif'or filename.endswith('bmp'or filename.endswith('jpeg'):  
  99.                 print 'downloading ' + filename  
  100.                 dist = dist.replace('\\', '/')  
  101.                 urllib.urlretrieve(filename, dist, None)  
  102.                 print "Done: ", filename  
  103.             qimg.task_done()  
  104.       
  105.     def run(self):  
  106.         while True:  
  107.             murl = qimg.get()  
  108.             print 'one '+murl  
  109.             filename = murl.split("/")[-1]  
  110.             urlopen = urllib.URLopener()  
  111.             try:  
  112.                 fp = urlopen.open(murl)  
  113.                 data = fp.read()  
  114.                 fp.close()  
  115.                 f = open(save_path + "/" + filename, 'w+b')  
  116.                 f.write(data)  
  117.                 f.close()  
  118.             except IOError:  
  119.                 print "download error!" + url  
  120.             qimg.task_done()  
  121.   
  122. if __name__ == "__main__":  
  123.     #===========================================================================  
  124.     # 抓取图片首个页面  
  125.     #===========================================================================  
  126.     url = "http://image.baidu.com"  
  127.     #url='http://bringgooglereaderback.com/'  
  128.     #===========================================================================  
  129.     # 图片保存路径  
  130.     #===========================================================================  
  131.       
  132.     if not os.path.exists(save_path):  
  133.         os.mkdir(save_path)  
  134.     #===========================================================================  
  135.     # 遍历深度  
  136.     #===========================================================================  
  137.     max_depth = 1  
  138.     main_site_domain = urlparse.urlsplit(url).netloc  
  139.     get_page_html(url, max_depth, main_site_domain)  
  140.       
  141.     for i in range(1):  
  142.         t = DPThread()  
  143.         t.setDaemon(True)  
  144.         t.start()  
  145.     qimg.join()  
  146.     print 'end'  

上面代码中有一个run方法和一个run3方法。

run3方法中使用urllib的urlretrieve来读取图片。发现这样速度很慢。所以直接在run方法中用了urllib的URLopener来打开图片地址并读取数据直接写到本地磁盘的文件中。

----------------------------------------------------------------------

遇到严重的问题:

由于一开始线程没有设置成Daemon的,所以即使Queue中没有内容了,脚本还是不会退出。设置成Daemon之后,在Queue中每有内容之后,脚本就会退出了。

---------------------------------------------------------

原因解释如下:

python中得thread的一些机制和C/C++不同:在C/C++中,主线程结束后,其子线程会默认被主线程kill掉。而在python中,主线程结束后,会默认等待子线程结束后,主线程才退出。

python对于thread的管理中有两个函数:join和setDaemon

  • join:如在一个线程B中调用threada.join(),则threada结束后,线程B才会接着threada.join()往后运行。
  • setDaemon:主线程A启动了子线程B,调用b.setDaemaon(True),则主线程结束时,会把子线程B也杀死,与C/C++中得默认效果是一样的。

python实现爬图,不要再爬妹子图了,太没品

随便找个有图片的网站,比如http://www.u148.net/article/37161.html,运行软件,将网址粘贴进去就行了,回车就行了。(linux下的路径,有需要的改改路径,很简单,做为...
  • han____shuai
  • han____shuai
  • 2015年07月31日 16:39
  • 959

Python3爬虫学习笔记2.2——爬图片-妹子图

有失远迎,今天尝试爬取妹子图妹子图。 让老司机飙车
  • sinat_31211873
  • sinat_31211873
  • 2016年08月28日 23:40
  • 2114

Python简单爬取图片实例

零基础详细讲解python爬取网站图片下载到本地的简单实例
  • Cloudox_
  • Cloudox_
  • 2016年12月05日 15:38
  • 13014

python爬虫-爬取美女图片

当你发现某个网站上有大量的美女图片,又非常想看,怎么办,网页上看?每次看的时候都得加载吧!No,你可以把这些图片都保存到本地,然后,在你想看的时候就可以随时看了,哈哈!多的不说。下面就来上代码: 1,...
  • guo_hongjun1611
  • guo_hongjun1611
  • 2016年01月25日 16:01
  • 2859

Python爬虫——爬取网站的图片

爬虫这东西最早出现在我大学计算机网络的课程上面,我们当时的老师人很好,期末不笔试,他说这东西笔试没什么用,对于一个年纪比较大的老师来讲,能提出这种方式,实在难得。当时在考虑做一个与网络有关的东西好,第...
  • iaiti
  • iaiti
  • 2015年11月19日 15:04
  • 25049

python多线程爬取图片

创建一个 Queue.Queue() 的实例,然后使用数据对它进行填充。 将经过填充数据的实例传递给线程类,后者是通过继承 threading.Thread 的方式创建的。 生成守护线程池。 每次从队...
  • jklfjsdj79hiofo
  • jklfjsdj79hiofo
  • 2014年10月30日 14:51
  • 1369

python爬图片的一个实例

拜读《python练习手册》之爬日本美女图图片,个人有一点体会: 在对网页打开时,有三种方式;列表内容 import re,urllib,osurl="http://tieba.baidu.com/p...
  • wjfzzhxy
  • wjfzzhxy
  • 2015年05月12日 17:24
  • 590

Python爬虫对知乎问题下的图片进行爬取

知乎的反爬做得很严格 1.翻页信息在首页的url不更新 2.要拿到所有图片需要翻页,同时不能用问题首页的url,信息所在如下图,翻页信息,data里面几乎有所有需要的信息 3.访问频率限制,这严...
  • Morzker
  • Morzker
  • 2017年08月20日 17:40
  • 504

好玩系列之python爬取图片

python3.6-爬虫-爬取图片
  • bearcatfly
  • bearcatfly
  • 2017年07月20日 23:27
  • 493

python爬虫(抓取百度图片)

一、python请求要抓取的url页面 【%E7%BE%8E%E5%A5%B3】urlcode解码之后就是【美女】 可以看到这是百度图片的api接口 :http://image.baidu....
  • lenovo403
  • lenovo403
  • 2016年02月23日 11:05
  • 10596
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:python爬图片
举报原因:
原因补充:

(最多只允许输入30个字)