python脚本编程:批量下载指定页面图片

【原文】http://my.oschina.net/tuxpy/blog/282607

python爬虫抓取制定网页内图片并保存到本地的方法一般有两个步骤。

步骤

步骤1:获取网页的html文档中指向图片的url

步骤2:从url中保存图片到本地

代码

单线程同步版

#coding:utf-8
import re
import urllib
import urllib2
import sys
import os
hds={'User-Agent':'chrome/28.0.1500.72',}
#proxy_h=urllib2.ProxyHandler({'http':'http://127.0.0.1:8087'})
"""如果需要账号密码认证,则需要使用proxy_a=urllib2.HTTPBasicAuthHandler().add_password('realm','host','username','password'),并把proxy_a传入urllib2.bulid_opener的第二个参数"""
#opener=urllib2.build_opener(proxy_h)
#urllib2.install_opener(opener) 
def getHtml(url):
    page=urllib2.urlopen(urllib2.Request(url,None,hds)).read() #读取网页html源码
    return page

def getImg(page):
    r_img=re.compile(r"src=\"((http://|https://|)[\w/\.\-/]*\.(jpg|png|gif))\"",re.I)#编译生成一个正则规则,匹配相对绝对,和多种图片格式
    for URL in  r_img.findall(page):#做一个遍历
        try:
            if not URL[1]:    #当它是相对路径时
                URL=Url+'/'+URL[0]  #把它变成绝对路径
            else:
                URL=URL[0]  #直接是绝对路径
            fileName=URL.split('/')[-1] #取文件名,从尾部分词
            print URL
            sURL=urllib2.Request(URL,None,hds)
            #sURL.add_header('Referer','http://desk.zol.com.cn/') #可选项,加上Referer,防止网站反爬虫

            #方法1
            urllib.urlretrieve(URL,fileName)

            #方法2
            #img=urllib2.urlopen(sURL).read()
            #open(fileName,'wb').write(img).close()

        except Exception,e:
            pass
if __name__ == '__main__':
    Url='http://desk.zol.com.cn/qiche/'   #也可以用命令行参数
    try:
        os.mkdir('img')  
    except OSError,e:
        if e.errno == 17:#如果是文件已经存在,则不做任何操作
            pass
        else:           #如果是其他异常,则打印出异常,并退出程序 
            print e
            sys.exit()
    os.chdir('img') #切换点这个目录
    getImg(getHtml(Url))

注意

  • 存储图片时,如果用open函数,则需要用wb模式而不是w模式,否则图片混乱。
  • 某些网站需要加入模拟浏览器浏览的头部以及Referer头部来骗过网站的防爬虫机制。

单线程异步版

#coding:utf-8
import re
import urllib2
import sys
import os
from twisted.internet import defer,reactor
from twisted.web.client import getPage
hds={'User-Agent':'chrome/28.0.1500.72',}
def getHtml(url):
    page=urllib2.urlopen(urllib2.Request(url,None,hds)).read() #读取网页html源码
    return page

def getImg(page):
    r_img=re.compile(r"src=\"((http://|https://|)[\w/\.\-/]*\.(jpg|png|gif))\"",re.I)#编译生成一个正则规则,匹配相对绝对,和多种图片格式

    urls=r_img.findall(page)
    dlist=[] # deferred列表

    def saveImg(img,filename):
        fd=open(filename,"wb")
        fd.write(img)
        fd.close()

    def getError(_):
        print _
        return None

    def getFinished(_):
        reactor.stop()


    for URL in  urls:#做一个遍历
        if not URL[1]:    #当它是相对路径时
            URL=Url+'/'+URL[0]  #把它变成绝对路径
        else:
            URL=URL[0]  #直接是绝对路径
        fileName=URL.split('/')[-1] #取文件名 
        print URL
        deferred=getPage(URL,timeout=3)
        dlist.append(deferred)
        deferred.addCallback(saveImg,fileName)
        deferred.addErrback(getError)
    d=defer.DeferredList(dlist)
    d.addBoth(getFinished) # 当列表中的deferred都激活后,才会激活这个


if __name__ == '__main__':
    Url=sys.argv[1]
    try:
        os.mkdir('img')
    except OSError,e:
        if e.errno == 17:#如果是文件已经存在,则不做任何操作
            pass
        else:           #如果是其他异常,则打印出异常,并退出程序 
            print e
            sys.exit()
    os.chdir('img') 
    d=getPage(Url)
    d.addCallback(getImg)
    reactor.run()

多线程版

#coding:utf-8
import re
import urllib2,urllib,socket
import sys
import os
import time
import threading
hds={'User-Agent':'chrome/28.0.1500.72',}
#proxy_h=urllib2.ProxyHandler({'http':'http://127.0.0.1:8087'})
#opener=urllib2.build_opener(proxy_h)
#urllib2.install_opener(opener)
def getHtml(url):
    page=urllib2.urlopen(urllib2.Request(url,None,hds)).read() #读取网页html源码
    return page
class getImgThread(threading.Thread):
    def __init__(self,imgUrl,fileName):
        threading.Thread.__init__(self)
        self.url=imgUrl
        self.fileName=fileName
    def run(self):
        mutex.acquire()
        print self.url
        mutex.release()
        urllib.urlretrieve(self.url,self.fileName)
if __name__ == '__main__':
    socket.setdefaulttimeout(10)
    Url=sys.argv[1]
    try:
        os.mkdir('img')
    except OSError,e:
        if e.errno == 17:#如果是文件已经存在,则不做任何操作
            pass
        else:           #如果是其他异常,则打印出异常,并退出程序 
            print e
            sys.exit()
    os.chdir('img') 
    page=getHtml(Url)
    r_img=re.compile(r"src=\"((http://|https://|)[\w/\.\-/]*\.(jpg|png|gif))\"",re.I)
    mutex=threading.Lock()
    threads=[]
    for URL in  r_img.findall(page):#做一个遍历
        try:
            if not URL[1]:    #当它是相对路径时
                URL=Url+'/'+URL[0]  #把它变成绝对路径
            else:
                URL=URL[0]  #直接是绝对路径
            fileName=URL.split('/')[-1] #取文件名 
            threads.append(getImgThread(URL,fileName))

        except Exception,e:
            pass
    for t in threads:
        t.start()
    for t in threads:
        t.join()
    print 'End'

效果

python脚本编程:批量下载指定页面图片_第1张图片

第一次体验csdn的markdown编辑器,好开心:)

你可能感兴趣的:(python)