python爬取某网站原图作为壁纸


Posted in Python onJune 02, 2021

不得不说 python真是一个神奇的东西,学三天就能爬网站 真香

完整代码

# -*- coding: utf-8 -*-
"""
Created on Wed May 26 17:53:13 2021

@author: 19088
"""
import urllib.request
import os
import pickle
import re
import random
import sys


#获取http代理
class getHttpAgents:
    #初始化函数
    def __init__(self):
        self.attArray=self.__loadAgentList()
        self.myagent=""
    
    #注意 返回对象未进行解码
    def openUrl(self,url,istry=1):
        response=""
        ip=""
        if(0 != len(self.myagent.strip())):
            ip=self.myagent
        i=1
        if not istry:
            i=99
        while i<100:
            try:
                #print(self.attArray)
                if(0 == len(self.attArray) and 0==len(ip.strip())):
                    req=urllib.request.Request(url)
                    #设置访问头
                    req.add_header("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.212 Safari/537.36")
                    response=urllib.request.urlopen(req)
                else:
                    if(0 != len(self.attArray)):
                        ip=random.choice(self.attArray)
                    if(0 != len(self.myagent.strip())):
                        ip=self.myagent
                    print("以{}访问 {}".format(ip,url))
                    #设置代理
                    proxy={"http":ip}
                    #print(proxy)
                    #定义一个代理字段
                    proxy_support=urllib.request.ProxyHandler(proxy)

                    #建立一个opener
                    opener=urllib.request.build_opener(proxy_support)
                    opener.addheaders=[("User-Agent","Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.212 Safari/537.36")]
                    #urllib.request.install_opener(opener)   
                    #获得网页对象
                    response=opener.open(url)
            except:
                if not istry:
                    print("{} 无法使用".format(ip))
                else:
                    print("第{}次尝试连接!".format(i))
            else:
                break;
            finally:
                i+=1
        if 11==i and istry:
            raise ValueError
        if not response:
            return 
        html=response.read()
        #print(html)
        return html

    #检查代理池 去除掉不可用代理ip
    def checkMyIpPool(self):
        agentsResult=[]
        agentList=self.attArray
        for iter in agentList:
            ip=iter
            self.setMyIp(ip)
            b=self.__getMyIp()
            if not b:
                #代理不能用
                #agentList.pop(-iter)
                pass
            else:
                agentsResult.append(ip)
                #print(b)
        #记录爬取过的可以使用的代理ip
        self.__writeAgentList(agentsResult)
        self.__setAgents(agentsResult)
        self.setMyIp("")
    
    #解析读取网页中所有的代理地址
    def getAgents(self,html):
        #print(html)
        #匹配 ip地址 正则表达式
        pattern = re.compile(r'(<td>)\s*((25[0-5]|2[0-4]\d|[0-1]\d\d|\d\d|\d)\.){3}(25[0-5]|2[0-4]\d|[0-1]\d\d|\d\d|\d)\s*</td>')
        ipList=[]
        ip=pattern.finditer(html)
        for ipiter in ip:
            ipText=ipiter.group()
            ipGroup=re.search(r"((25[0-5]|2[0-4]\d|[0-1]\d\d|\d\d|\d)\.){3}(25[0-5]|2[0-4]\d|[0-1]\d\d|\d\d|\d)", ipText)
            ipList.append(ipGroup.group())

        #匹配 端口地址 正则表达式
        portList=[]
        pattern = re.compile(r'(<td>)\s*\d+\s*</td>')
        port = pattern.finditer(html) 
        for portiter in port:
            portText=portiter.group()
            portGroup=re.search(r"\d+", portText)
            portList.append(portGroup.group())

        if(len(ipList) is not len(portList)):
            print("注意: ip和端口参数不匹配!")
            return
        ipDict=dict(zip(ipList,portList))

        agentList=[]
        for key in ipDict:
            agentList.append(key+":"+ipDict.get(key))  
        agentsResult=[]
        for iter in agentList:
            ip=iter
            self.setMyIp(ip)
            b=self.__getMyIp()
            if not b:
                #代理不能用
                pass
                #agentList.pop(-iter)
            else :
                agentsResult.append(ip)
                self.__setAgents(agentsResult)
                print("{} 可以使用".format(ip))
        agentsResult.extend(self.attArray)  
        #记录爬取过的可以使用的代理ip
        if(0==len(agentsResult)):
            return
        self.__writeAgentList(agentsResult)
        self.__setAgents(agentsResult)
        self.setMyIp("")
        return agentList

    
    def __setAgents(self,ipArray):
        self.attArray=ipArray
    def setMyIp(self,ip):
        self.myagent=ip
    #存储爬取过的ip代理
    def __writeAgentList(self, agentList): 
        if os.path.exists("agent.pkl"):
            os.remove("agent.pkl")          #每次重新生成 要不多次 dump需要多次 load
        with open("agent.pkl.","wb") as f:
            pickle.dump(agentList, f)
        print("存储{}条代理".format(len(agentList)))
    
    #加载之前存储过的ip代理
    def __loadAgentList(self):
        agentlist=[]
        if not os.path.exists("agent.pkl"):
            return agentlist
        with open("agent.pkl","rb") as f:
            agentlist=pickle.load(f)
            print("加载{}条代理".format(len(agentlist)))
            return agentlist

    #获取当前使用的ip地址 类的内部方法 仅供内部调用
    def __getMyIp(self,ip=""):
        url="https://www.baidu.com/"
        html=""
        try:
            html=self.openUrl(url,0).decode("utf-8")
        except:
            return 
        #匹配ip地址
        #pattern = re.compile(r'((25[0-5]|2[0-4]\d|[0-1]\d\d|\d\d|\d)\.){3}(25[0-5]|2[0-4]\d|[0-1]\d\d|\d\d|\d)')
        #groupIp=pattern.search(html)
        #if groupIp:
            #return groupIp.group()
        else:
            return html
    
    #通过不同的网站去爬取代理
    def crawlingAgents(self,index):
        try:
            url ="http://ip.yqie.com/ipproxy.htm"
            print(url)
            html=self.openUrl(url) 
            html=html.decode("utf-8") 
            self.setMyIp("")                                                #不指定ip 随机挑选一个作为代理
            self.getAgents(html)
        except Exception as e:
            print("{} 爬取失败".format(url))
        
        #一共搜集多少页
        page=index
        
        indexCur=1
        while indexCur<=page:
            try:
                url=r"https://www.89ip.cn/index_{}.html".format(indexCur)
                print(url)
                self.setMyIp("") 
                html=self.openUrl(url)                                               #不指定ip 随机挑选一个作为代理
                html=html.decode("utf-8")
                self.getAgents(html)
            except Exception as e:
                print("{} 爬取失败".format(url))
            finally:
                indexCur+=1
        
        indexCur=1
        while indexCur<=page:
            try:
                url=r"http://www.66ip.cn/{}.html".format(indexCur)
                print(url)
                self.setMyIp("") 
                html=a.openUrl(url)                                               #不指定ip 随机挑选一个作为代理
                html=html.decode("UTF-8")
                self.getAgents(html)
            except Exception as e:
                print("{} 爬取失败".format(url))
            finally:
                indexCur+=1                                  

        indexCur=1
        while indexCur<=page:
            try:
                url=r"http://www.ip3366.net/?stype=1&page={}".format(indexCur)
                print(url)
                self.setMyIp("") 
                html=a.openUrl(url)                                               #不指定ip 随机挑选一个作为代理
                html=html.decode("UTF-8")
                self.getAgents(html)
            except Exception as e:
                print("{} 爬取失败".format(url))
            finally:
                indexCur+=1  

        indexCur=1
        while indexCur<=page:
            try:
                url=r"http://www.kxdaili.com/dailiip/1/{}.html".format(indexCur)
                print(url)
                self.setMyIp("") 
                html=a.openUrl(url)                                               #不指定ip 随机挑选一个作为代理
                html=html.decode("utf-8")
                self.getAgents(html)
            except Exception as e:
                print("{} 爬取失败".format(url))
            finally:
                indexCur+=1


#下载图片封装类
class downLoadPictures:
    #构造函数
    def __init__(self):
        self.sortKey={}                                 #定义一个搜索关键字的字典
        self.urlLoad=getHttpAgents()
        self.bzmenuDict={}                              #分类信息 风景 美女 什么的分类
        self.sortscreenDict={}                          #按照屏幕尺寸分类
        self.littleSignDict={}                          #分类信息下面的小分类
        pass
    
    
    def getPictures(self,url):
        #第一步 打开网页 读取page信息 
        pagerHtml=self.urlLoad.openUrl(url)
        #第二步 获取 pageFolder 链接和各种分类信息 返回的是一堆folder链接的url
        folderPictursUrl=self.readPages(pagerHtml).values()
        if not folderPictursUrl:
            print("获取图片集失败!")
            return
        for floderiterUrl in folderPictursUrl:
            folderUrl=str("https://www.ivsky.com/")+floderiterUrl
            folderHtml=self.urlLoad.openUrl(folderUrl)
            #第三步 读取图片集 获取单个图片的链接地址 返回的是图片集里面的一堆文件url
            pictursUrlDict=self.readFolders(folderHtml)
            for iterPictureKey in pictursUrlDict:
                fileName=iterPictureKey+".jpg"
                pictureUrl=str("https://www.ivsky.com/")+pictursUrlDict.get(iterPictureKey)
                
                #读取图片页相关信息
                pictureHtml=self.urlLoad.openUrl(pictureUrl)
                picturDownUrl=self.readPictures(pictureHtml)
                pictureDownHtml=self.urlLoad.openUrl(picturDownUrl)
                if not pictureDownHtml:
                    continue
                #保存图片
                with open(fileName,"wb+") as f:
                    f.write(pictureDownHtml)
        
    
    #提取匹配内容中的所有链接地址
    def getHrefMap(self,html,isPicture=0,isFolder=0):
        hrefDict={}
        pattern=re.compile(r'<a\s*.*?\s*</a>',re.I)
        if isPicture:
            pattern=re.compile(r'<p>\s*?<a\s*.*?</p>',re.I)
        hrefIter=pattern.finditer(html)
        index=0
        for iter in hrefIter:
            hrefText=iter.group()
            #匹配分类名字
            pattern=re.compile(r'"\s*?>\s*?.*?</a>',re.I)
            name=""
            nameGroup=pattern.search(hrefText)
            if nameGroup:
                name=nameGroup.group()
                if(5==len(nameGroup.group().replace(" ", ""))):
                    pattern=re.compile(r'title=".*?"',re.I)
                    nameGroup=pattern.search(hrefText)
                    if nameGroup:
                        name=nameGroup.group()[7:-1]
                name=name[2:-4].replace(" ", '')
            #匹配href
            pattern=re.compile(r'href=".*?" rel="external nofollow" ',re.I)
            url=""
            urlGroup=pattern.search(hrefText)
            if urlGroup:
                url=urlGroup.group()[6:-1].replace(" ", '')
            if isFolder:
                index+=1
                name+="_"+str(index)
            hrefDict[name]=url
        return hrefDict
     #读取首页信息 包含各种分类的链接地址 以及图片集的地址集合   
    def readPages(self,html):
        html=html.decode("utf-8")
        #检索壁纸分类
        #匹配 壁纸分类信息
        pattern=re.compile(r'<ul\s*class="bzmenu".*?</ul>',re.I)
        sortClassGroup=pattern.search(html)
        if sortClassGroup:
            sortMessage=sortClassGroup.group()
            self.bzmenuDict=self.getHrefMap(sortMessage)
            #print(self.bzmenuDict)
        else:
            print("匹配壁纸分类出错!")
            return
        
         #匹配 按照屏幕大小分类
        pattern=re.compile(r'<ul\s*class="sall_dd".*?</ul>',re.I)
        sortClassGroup=pattern.search(html)
        if sortClassGroup:
            sortMessage=sortClassGroup.group()
            self.sortscreenDict=self.getHrefMap(sortMessage)
            #print(self.sortscreenDict)
        else:
            print("匹配屏幕尺寸分类失败!")
            return       
       
         #匹配 获取小分类
        pattern=re.compile(r'<div\s*class="sline".*?</div>',re.I)
        sortClassGroup=pattern.search(html)
        if sortClassGroup:
            sortMessage=sortClassGroup.group()
            #print(sortMessage)
            self.littleSignDict=self.getHrefMap(sortMessage)
            #print(self.littleSignDict)
        else:
            print("匹配小分类失败")
            return               
        
        pictureDict={}
        #匹配 图片集地址
        pattern=re.compile(r'<ul\s*class="ali".*?</ul>',re.I)
        sortClassGroup=pattern.search(html)
        if sortClassGroup:
            sortMessage=sortClassGroup.group()
            pictureDict=self.getHrefMap(sortMessage,1)
            #print(pictureDict)
        else:
            print("匹配图片集地址失败!")
            return         
        #print(html)
        return pictureDict
    
    #解析每个图片集合对应的图片集内容 解析出单个图片的链接地址
    def readFolders(self,html):
        if not html:
            return
        html=html.decode("utf-8")
        
        #获取图片集里面每个图片的具体地址和名称
         #匹配 获取小分类
        pattern=re.compile(r'<ul\s*class="pli".*?</ul>',re.I)
        sortClassGroup=pattern.search(html)
        pictureUrlDict={}
        if sortClassGroup:
            sortMessage=sortClassGroup.group()
            #print(sortMessage)
            pictureUrlDict=self.getHrefMap(sortMessage,1,1)
            #print(pictureUrlDict)
        else:
            print("匹配小分类失败")
            return                            
        return pictureUrlDict
    
    #解析每个图片集合对应的图片集内容 解析出单个图片的链接地址
    def readPictures(self,html):
        if not html:
            return        
        html=html.decode("utf-8")
        #获取图片集里面每个图片的具体地址和名称
         #匹配 获取小分类
        pattern=re.compile(r'<div\s*class="pic".*?</div>',re.I)
        sortClassGroup=pattern.search(html)
        pictureUrl=""
        if sortClassGroup:
            sortMessage=sortClassGroup.group()
            #匹配href
            pattern=re.compile(u"src='.*?'",re.I)
            url=""
            urlGroup=pattern.search(sortMessage)
            if urlGroup:
                url=urlGroup.group()[5:-1].replace(" ", '')            
            url=url.replace('img-pre', 'img-picdown')
            url=url.replace('pre', 'pic')
            url=str("https:")+url
            #print(sortMessage)
            pictureUrlDict=url
            #print(url)
        else:
            print("匹配小分类失败")
            return                            
        return pictureUrlDict        
        

class UrlUser:
    
    def __init__(self):
        self.agent=getHttpAgents()
        self.downPicture=downLoadPictures()   
    
    #下载图片调用函数
    def downPictures(self):

        #url="https://www.ivsky.com/bizhi"
        #b.getPictures(url)
        #确定保存路径      
        dirPath=input("请输入保存路径:")
        if not os.path.exists(dirPath):
            os.mkdir(dirPath)
        if not os.path.isdir(dirPath):
            print("savePath is wrong!")
            sys.exit()
        os.chdir(dirPath)                                       #切换工作目录 
        #url=r"https://www.ivsky.com/bizhi/nvxing_1920x1080/index_{}.html"
        page=input("爬取前多少页的图片?\n")
        indexRe = re.search(r"\d+", page)
        if(not indexRe):
            print("输入页数有误!")
        indexRe=int(indexRe.group())
        indexCur=1
        while indexCur<=indexRe:
            try:
                #注意 爬取什么类型的图片可以根据不同的网址进行设计 下载类里面已经读取了所有分类对应的地址 有兴趣可以自己完善
                url=r"https://www.ivsky.com/bizhi/nvxing_1920x1080/index_{}.html".format(indexCur)
                print(url)
                self.downPicture.getPictures(url)
            except:
                print("打开出错!")
                pass
            finally:
                indexCur+=1

    #爬取代理
    def downAgents(self):
        page=input("爬取前多少页的代理?\n")
        indexRe = re.search(r"\d+", page)
        if(not indexRe):
            print("输入页数有误!")
            return
        indexRe=int(indexRe.group())    
        self.agent.crawlingAgents(indexRe)
    
    # 检查当前代理池是否可以
    def checkPool(self):
        self.agent.checkMyIpPool() 
        
if __name__ == "__main__":
    print("*"*20)
    print("1.爬取代理\n")
    print("2.检查代理\n")
    print("3.爬取图片")   
    print("*"*20)
    mode=input("请输入数字选择处理模式:\n")
    indexRe = re.search(r"\d+", mode)
    if(not indexRe):
        print("输入页数有误!")
        sys.exit()
    indexRe=int(indexRe.group())
    #实例化一个对象
    uesrObj=UrlUser()
    
    if 1 == indexRe:
        uesrObj.downAgents()
    elif 2 == indexRe:
        uesrObj.checkPool()
    elif 3 == indexRe:
        uesrObj.downPictures()
    else:
        print("模式选择错误!")
        sys.exit()
    print("爬取完毕!")

效果图

python爬取某网站原图作为壁纸

Python 相关文章推荐
深入理解python中的浅拷贝和深拷贝
May 30 Python
python的exec、eval使用分析
Dec 11 Python
Python基于递归算法求最小公倍数和最大公约数示例
Jul 27 Python
Python实现定时执行任务的三种方式简单示例
Mar 30 Python
Python爬取破解无线网络wifi密码过程解析
Sep 17 Python
创建Shapefile文件并写入数据的例子
Nov 26 Python
Python 词典(Dict) 加载与保存示例
Dec 06 Python
python3 tcp的粘包现象和解决办法解析
Dec 09 Python
Python BeautifulReport可视化报告代码实例
Apr 13 Python
python实现扑克牌交互式界面发牌程序
Apr 22 Python
django model 条件过滤 queryset.filter(**condtions)用法详解
May 20 Python
Python 爬虫的原理
Jul 30 Python
Python爬虫之自动爬取某车之家各车销售数据
从np.random.normal()到正态分布的拟合操作
golang特有程序结构入门教程
Jun 02 #Python
Python中的np.argmin()和np.argmax()函数用法
Jun 02 #Python
python之np.argmax()及对axis=0或者1的理解
Python import模块的缓存问题解决方案
Jun 02 #Python
Python3 类型标注支持操作
Jun 02 #Python
You might like
Oracle 常见问题解答
2006/10/09 PHP
php excel类 phpExcel使用方法介绍
2010/08/21 PHP
在PHP模板引擎smarty生成随机数的方法和math函数详解
2014/04/24 PHP
PHP动态规划解决0-1背包问题实例分析
2015/03/23 PHP
利用“多说”制作留言板、评论系统
2015/07/14 PHP
在Mac上编译安装PHP7的开发环境
2015/07/28 PHP
PHP设计模式之迭代器模式
2016/06/17 PHP
PHP如何通过带尾指针的链表实现'队列'
2020/10/22 PHP
JavaScript在多浏览器下for循环的使用方法
2012/11/07 Javascript
用Javascript获取页面元素的具体位置
2013/12/09 Javascript
Javascript中的方法链(Method Chaining)介绍
2015/03/15 Javascript
JQuery实现鼠标滚轮滑动到页面节点
2015/07/28 Javascript
jquery实现九宫格大转盘抽奖
2015/11/13 Javascript
jQuery日历插件datepicker用法详解
2016/03/03 Javascript
表单中单选框添加选项和移除选项
2016/07/04 Javascript
原生js仿jquery实现对Ajax的封装
2016/10/04 Javascript
Bootstrap免费字体和图标网站(值得收藏)
2017/03/16 Javascript
Vue动态组件实例解析
2017/08/20 Javascript
vuejs使用$emit和$on进行组件之间的传值的示例
2017/10/04 Javascript
使用vue2实现带地区编号和名称的省市县三级联动效果
2018/11/05 Javascript
解决vue项目router切换太慢问题
2020/07/19 Javascript
详解JavaScript自定义函数
2020/07/29 Javascript
[03:35]2018年度DOTA2最佳辅助位选手5号位-完美盛典
2018/12/17 DOTA
Python天气预报采集器实现代码(网页爬虫)
2012/10/07 Python
Python编程中的文件读写及相关的文件对象方法讲解
2016/01/19 Python
Python使用matplotlib绘制多个图形单独显示的方法示例
2018/03/14 Python
python DataFrame获取行数、列数、索引及第几行第几列的值方法
2018/04/08 Python
详解python中的线程与线程池
2019/05/10 Python
企业管理毕业生求职信
2014/03/11 职场文书
推普周国旗下讲话稿
2014/09/21 职场文书
2014年团支部工作总结
2014/11/17 职场文书
目标责任书格式范文
2015/05/11 职场文书
小学家长意见怎么写
2015/06/03 职场文书
师范生小学见习总结
2015/06/23 职场文书
2016母亲节感恩话语
2015/12/09 职场文书
Python函数对象与闭包函数
2022/04/13 Python