zoukankan      html  css  js  c++  java
  • python抓取网页图片

    python抓取网页图片

    网页的图片大致是用Image导入的,使用的是相对路径,例如

    <image src="image/bg.jpg"/>

    通过匹配可以获取image/bg.jpg,与页面地址组合可以得到图片的地址

    除了直接引入的图片,还有通过CSS,HTML引入的图片,也需要处理

    复制代码
    # -*- coding: utf-8 -*-
    import urllib, httplib, urlparse
    import sys
    import re
    
    def httpExists(url):
        host, path = urlparse.urlsplit(url)[1:3]
        if ':' in host:
            # port specified, try to use it
            host, port = host.split(':', 1)
            try:
                port = int(port)
            except ValueError:
                print 'invalid port number %r' % (port,)
                return False
        else:
            # no port specified, use default port
            port = None
        try:
            connection = httplib.HTTPConnection(host, port=port)
            connection.request("HEAD", path)
            resp = connection.getresponse( )
            if resp.status == 200:       # normal 'found' status
                found = True
            elif resp.status == 302:     # recurse on temporary redirect
                found = httpExists(urlparse.urljoin(url,resp.getheader('location', '')))
            else:                        # everything else -> not found
                print "Status %d %s : %s" % (resp.status, resp.reason, url)
                found = False
        except Exception, e:
            print e.__class__, e, url
            found = False
        return found
    
    """根据url获取文件名"""
    def gGetFileName(url):
        if url==None: return None
        if url=="" : return ""
        arr=url.split("/")
        return arr[len(arr)-1]
    
    """根据url下载文件,文件名参数指定"""
    def gDownloadWithFilename(url,savePath,file):
        #参数检查,现忽略
        try:
            urlopen=urllib.URLopener()
            fp = urlopen.open(url)
            data = fp.read()
            fp.close()
            print 'download file url :',url
            file=open(savePath + file,'w+b')
            file.write(data)
            file.close()
        except IOError:
            print "download error!"+ url
    
    def gDownload(url,savePath):
    
        fileName = gGetFileName(url)
        gDownloadWithFilename(url,savePath,fileName)
    
    def getRexgList(lines,regx,searchRegx):
        if lines==None : return 
        lists =[]
        for line in lines:
            ismatch = re.search(regx,line,re.IGNORECASE)
            if ismatch :
               
                matchs = re.search(searchRegx,line,re.IGNORECASE)
                if matchs != None:
                    groups = matchs.groups()
                    for str in groups:
                        if str not in lists:
                            lists.append(str)
        return lists
    def checkLine(lines):
        for line in lines :
            matchs = re.search(r'url((S+))',re.IGNORECASE)
            if matchs != None :
                print matchs.groups()
    def  getPageLines(url):
        if url==None : return
        if not httpExists(url): return 
        try:
            page = urllib.urlopen(url)   
            html = page.readlines()
            page.close()
            return html
        except:
            print "getPageLines() error!"
            return
    def getCurrentPageImage(url,savePath):
        lines = getPageLines(url)
        print 'lines.length',len(lines)
       
        regxlists =  getRexgList(lines,r'srcs*="images(S+)"',r'srcs*="(S+)"')
        if regxlists==None: return 
        print 'getCurrentPageImage() images.length',len(regxlists)
        for jpg in regxlists:
            jpg =url + jpg
            gDownload(jpg,savePath)
    
    def getCSSImages(link,savePath,url):
        lines = getPageLines(link)
        print 'lines.length',len(lines)
        regxlists =  getRexgList(lines,r'url((S+))',r'url((S+))')
        if regxlists==None: return 
        print 'getCurrentPageImage() images.length',len(regxlists)
        for jpg in regxlists:
            jpg =url + jpg
            gDownload(jpg,savePath)
    
    """根据url获取其上的相关htm、html链接,返回list"""
    def gGetHtmlLink(url):
        #参数检查,现忽略
        rtnList=[]
        lines=getPageLines(url)
        regx = r"""href="?(S+).htm"""
        for link in getRexgList(lines,regx,r'href="(S+)"'):
            link =url + link
            if link not in rtnList:
                rtnList.append(link)
                print link
        return rtnList
    """根据url获取其上的相关css链接,返回list"""
    def gGetCSSLink(url):
        #参数检查,现忽略
        rtnList=[]
        lines=getPageLines(url)
        regx = r"""href="?(S+).css"""
        for link in getRexgList(lines,regx,r'href="(S+)"'):
            link = url + link
            if link not in rtnList:
                rtnList.append(link)
        return rtnList   
    def getPageImage(url,savePath):
        """getCurrentPageImage(url,savePath)"""
    
        """读取其他的CSS,html文件中的图片
        links=gGetHtmlLink(url)
        for link in links:
            print u'get images on link-html读取'
            getCurrentPageImage(link,savePath)"""
        links=gGetCSSLink(url)
        for link in links:
            print 'get images on link:',link
            getCSSImages(link,savePath,url)
    if __name__ == '__main__':
        
        url = 'http://www.templatemo.com/templates/templatemo_281_chrome/'
        savePath = 'd:/tmp/'
        print 'download pic from [' + url +']'
        print 'save to [' +savePath+'] ...'
        getPageImage(url,savePath)
        print "download finished"
    复制代码

    具体使用的时候根据URL的情况,具体分析得到图片地址的方式。

     

    红黑树:个人理解与Python实现

    红黑树:个人理解与Python实现
    
    【基本事实1】
    红黑树是一种平衡的二叉查找树,无论插入还是删除操作都可以在O(lg n)内实现,而一般的二叉查找树则在极端情况下会退化为线性结构。
    红黑树之所以是平衡的二叉查找树,是因为每个节点都有表示其颜色的域值:红或黑,在插入和删除操作的时候依据节点的颜色向平衡的方向调整。根本原因当然是由红黑树定义所决定的:
    如果一个二叉查找树满足如下条件,那么它就称作红黑树:
    1.每个节点要么是红色,要么是黑色
    2.根结点是黑色
    3.每个叶节点(NIL)为黑色
    4.如果一个节点是红色,其儿子节点一定是黑色
    5.对于每个节点,从该节点到其子孙节点的所有路径上包含相同数目的黑节点
    
    【个人理解1】
    红黑树的定义中,我认为有这些地方要注意:
    1.每个节点只有一种颜色(后面删除节点的操作时引入的“额外一重黑色”则不满足此条件,所以一直要性质1调整)
    2.定义中的叶节点是指NIL,它们都是黑色,而且没有子节点。根结点的父节点也是NIL。比如只有一个根节点的红黑树,它有两个叶节点。NIL是没有值的,只是一种存在。(我在Python的实现中,把NIL值都设定为None3.如果一个节点是红色的,它一定不是根结点,而且一定有父节点(父节点也一定是黑色的);如果它有儿子节点则一定是黑色儿子节点(每个节点如果左右儿子都是NIL,我认为它没有儿子)
    4.性质5说的就是黑高度了
    
    【基本事实2】
    红黑树的旋转
    红黑树在INSERTDELETE的过程中,会使用到旋转操作。红黑树有两种旋转:左旋和右旋
    

    左旋x:从右图到左图的过程
    右旋y:从左图到右图的过程 【个人理解21.并非每个节点在INSERTDELETE的过程中都需要旋转操作 2.左旋就是右儿子y取代父节点xx作为y的做儿子,y原来的左儿子b成为x现在的右儿子 3.右旋就是左旋的逆向过程 【基本事实3】 红黑树的插入 INSERT一个值的过程,就是在二叉查找树的INSERT操作基础上,根据红黑树性质做必要的调整,比如颜色变化,比如旋转,也就是INSERT_FIXUP的过程 插入的节点一般设定为红色然后再调整 【个人理解3】 假设要插入的节点为zINSERT操作就是把z放到树的最底层,然后用INSERT_FIXUP区调整。INSERT_FIXUP中要注意的是: 1.如果z的父节点是NIL(即:插入节点z之前红黑树为空),那么把z涂黑,并成为根结点(完成插入) 2.如果z的父节点是黑色的,不用调整(完成插入) 3.如果z的父节点是红色的: 3-0:如果z没有叔叔节点,那么: 3-0-0:如果z为右儿子,则左旋z的父节点,成为3-0-1 3-0-1:如果z为左儿子,则“父涂黑,爷涂红”,然后如果父节点是左儿子,则“爷右旋”,否则“爷左旋”(完成插入) 3-1:如果z的叔叔节点为黑色,那么: 3-1-0:如果z是右儿子,那么左旋z的父节点,转化为3-1-1 3-1-1:如果z是左儿子,那么“父涂黑,爷涂红”,然后如果父节点是左儿子,则“爷右旋”,否则“爷左旋”(完成插入) 3-2:如果z的叔叔节点为红色,那么“父涂黑,叔涂黑,爷涂红”,并对爷爷节点g调用INSERT_FIXUP过程 以上序号和《算法导论》中的对应关系:3-2对应case13-1-0对应case23-1-1对应case3 【基本事实41.红黑树删除一个节点的操作比较复杂,但也是在二叉查查找树的基础上,调用DELETE_FIXUP过程来调整 2.如果要删除的节点z,它有两个儿子,那么让z的值设定为z的后继节点y的值,然后删除y 3.如果要删除的节点z只有一个儿子x,那就让z的节点px成为“父子”。如果z原来是红色的,则不必调用DELETE_FIXUP过程,否则要调用 4.如果要删除的节点z没有儿子:那就直接删除z好了 5.删除节点时引入了“额外的一层黑色”,《算法导论》中文第二版P173这样说: “在RB—DELETE中,如果被删除的节点y是黑色的,则会产生三个问题。首先,如果y原来是根结点,而y的一个红色的孩子成为了新的根,这就问犯了性质2)。其次,如果xp[y](现在也是p[x])都是红的,就违反了性质4)。第三,删除y将导致先前包含y的任何路径上黑节点个数少1。因此,性质5)被y的一个祖先破坏了。不久者恶问题的一个办法就是把结点x视为还有额外的一重黑色。也就是说,如果将人以包含结点x的路径上黑节点个数加1,则在这种假设下,性质5)成立。当将黑节点y删除时,将其黑色“下推”至其子节点。现在为题变为结点x可能既不是红,又不是黑,从而违反了性质1)。结点x是双重黑色或红黑,这就分别给包含x的路径上黑结点个数贡献2个或1个。xcolor属性仍然是RED(如果x是红黑的)或BLACK(如果x是双重黑色)。换言之,一个结点额外的黑色反映在x指向它,而不是它的color属性。” 【个人理解41.当你想举反例推翻某个“结论”时,请注意,你的反例中的红黑树可能并不是红黑树;或者,它满足红黑树的定义,但无法判断是否能通过“每次插入一个节点”的方式生成。 2.因为有“额外一重黑色”的存在,《算法导论》中关于红黑树删除的case1中,调整前后的两幅图虽然“看上去是镜面对称”,但前者不满足性质5,调整后满足性质5 3.《算法导论》中关于红黑树删除的case2中,x现在为黑色,且有额外的一重黑色(就像是背负着子孙们的希望。。。),此时将xw都去掉一个黑色,然后使px)增加额外的一层黑色。由于w原本为黑色,则现在令w为红色即可。此时令new_x=p(x),若new_x原本为红色,置黑即可结束;否则,对new_x调用DELETE_FIXUP过程 4.DELETE_FIXUP过程,调整的是DELETE(z)过程中z的左/右儿子(z只有一个儿子时),或者z的后继的右儿子


    我的代码:
    #coding:utf8#author:HaxtraZ#description:红黑树,python实现
    
    
    RED ='red'
    BLACK ='black'class RBT:def __init__(self):self.items =[]self.root =Nonedef LEFT_ROTATE(self, x):# x是一个RBTnode
            y = x.right
            if y isNone:# 右节点为空,不旋转returnelse:
                beta = y.left
                x.right = beta
                if beta isnotNone:
                    beta.parent = x
    
                p = x.parent
                y.parent = p
                if p isNone:# x原来是rootself.root = y
                elif x == p.left:
                    p.left = y
                else:
                    p.right = y
                y.left = x
                x.parent = y
    
        def RIGHT_ROTATE(self, y):# y是一个节点
            x = y.right
            if x isNone:# 右节点为空,不旋转returnelse:
                beta = x.right
                y.left = beta
                if beta isnotNone:
                    beta.parent = y
    
                p = y.parent
                x.parent = p
                if p isNone:# y原来是rootself.root = x
                elif y == p.left:
                    p.left = x
                else:
                    p.right = x
                x.right = y
                y.parent = x
    
        def INSERT(self, val):
            z =RBTnode(val)
            y =None
            x =self.root
            while x isnotNone:
                y = x
                if z.val < x.val:
                    x = x.left
                else:
                    x = x.right
    
            z.PAINT(RED)
            z.parent = y
    
            if y isNone:# 插入z之前为空的RBTself.INSERT_FIXUP(z)elif y.color == RED:# z的父节点y为红色,需要fixup。# 如果z的父节点y为黑色,则不用调整if z.val < y.val:
                    y.left = z
                else:
                    y.right = z
                self.INSERT_FIXUP(z)def INSERT_FIXUP(self, z):# case 1:z为root节点ifself.root ==None:
                z.PAINT(BLACK)self.root = z
                return# case 2:z的父节点为黑色ifself.parent.color == BLACK:# 包括了z处于第二层的情况return# 下面的几种情况,都是z.parent.color == RED:# 节点y为z的uncle
            p = z.parent
            if p == p.parent.left:
                y = p.parent.right
            else:
                y = p.parent.left
    
            g = p.parent  # g为x的grandpa# case 3-0:z没有叔叔。即:y为NIL节点# 注意,此时z的父节点一定是REDif y isNone:if z == p.left:# 3-0-0:z为右儿子,则把p左旋# 转化为3-0-1或3-0-2的情况self.LEFT_ROTATE(p)
                    p, z = z, p
                g.PAINT(RED)
                p.PAINT(BLACK)if g.left == p:# 3-0-1:p为g的左儿子self.RIGHT_ROTATE(g)else:# 3-0-2:p为g的右儿子self.LEFT_ROTATE(g)# case 3-1:z有黑叔elif y.color == BLACK:if p.right == z:# 3-1-0:z为右儿子,则左旋p# 转化为3-1-1或3-1-2self.LEFT_ROTATE(p)
                    p, z = z, p
    
                p.PAINT(BLACK)
                g.PAINT(RED)if p == g.left:# 3-1-1:p为g的左儿子,则右旋gself.RIGHT_ROTATE(g)else:# 3-1-2:p为g的右儿子,则左旋gself.LEFT_ROTATE(g)# case 3-2:z有红叔# 则涂黑父和叔,涂红爷,g作为新的z,递归调用else:
                y.PAINT(BLACK)
                p.PAINT(BLACK)
                g.PAINT(RED)self.INSERT_FIXUP(g)def DELETE(self, val):
            curNode =self.root
            while curNode isnotNone:if val < curNode.val:
                    curNode = curNode.left
                elif val > curNode.val:
                    curNode = curNode.right
                else:# 找到了值为val的元素,正式开始删除if curNode.left isNoneand curNode.right isNone:# case1:curNode为叶子节点:直接删除即可if curNode ==self.root:self.root =Noneelse:
                            p = curNode.parent
                            if curNode == p.left:
                                p.left =Noneelse:
                                p.right =Noneelif curNode.left isnotNoneand curNode.right isnotNone:
                        sucNode =self.SUCCESOR(curNode)
                        curNode.val, sucNode.val  = sucNode.val, curNode.val
                        self.DELETE(sucNode.val)else:
                        p = curNode.parent
                        if curNode.left isNone:
                            x = curNode.right
                        else:
                            x = curNode.left
                        if curNode == p.left:
                            p.left = x
                        else:
                            p.right = x
                        x.parent = p
                        if curNode.color == BLACK:self.DELETE_FIXUP(x)
    
    
                    curNode =NonereturnFalsedef FIND(self, val):classRBTnode:'''红黑树的节点类型'''def __init__(self, val):self.val = val
            self.left =Noneself.right =Noneself.parent =Nonedel PAINT(self, color):self.color = color

      

    作者:HaxtraZ
    除非另有声明,本网站采用知识共享 “署名 2.5中国大陆” 许可协议授权
     
    分类: Python
     
    分类: python
  • 相关阅读:
    redis主从配置
    mysql被动模式下的主主配置
    centos7 重启网卡报错
    mysql innodb_data_file_path配置增加
    sql语句偶记录
    nginx 做前端代理时proxy参数配置
    firewalld实现网关功能
    mysql负载飙高原因分析
    nginx 直接返回状态码
    (转)Yale CAS + .net Client 实现 SSO(6)
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/3280909.html
Copyright © 2011-2022 走看看