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变量与常量
Jun 02 Python
python在ubuntu中的几种安装方法(小结)
Dec 08 Python
Python中摘要算法MD5,SHA1简介及应用实例代码
Jan 09 Python
Python实现的凯撒密码算法示例
Apr 12 Python
Python(Django)项目与Apache的管理交互的方法
May 16 Python
Python根据文件名批量转移图片的方法
Oct 21 Python
python实现整数的二进制循环移位
Mar 08 Python
详解Python函数式编程—高阶函数
Mar 29 Python
python_matplotlib改变横坐标和纵坐标上的刻度(ticks)方式
May 16 Python
python接口自动化之ConfigParser配置文件的使用详解
Aug 03 Python
pytorch显存一直变大的解决方案
Apr 08 Python
详解Python如何批量采集京东商品数据流程
Jan 22 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
一个程序下载的管理程序(三)
2006/10/09 PHP
zf框架的session会话周期及次数限制使用示例
2014/03/13 PHP
php中的curl使用入门教程和常见用法实例
2014/04/10 PHP
PHP论坛实现积分系统的思路代码详解
2020/06/01 PHP
js网页侧边随页面滚动广告效果实现
2011/04/14 Javascript
JavaScript包装对象使用详解
2015/07/09 Javascript
深入理解JavaScript中的call、apply、bind方法的区别
2016/05/30 Javascript
JS留言功能的简单实现案例(推荐)
2016/06/23 Javascript
AngularJS基础 ng-srcset 指令简单示例
2016/08/03 Javascript
老生常谈javascript的类型转换
2016/10/12 Javascript
jQuery autoComplete插件两种使用方式及动态改变参数值的方法详解
2016/10/24 Javascript
老生常谈的跨域处理
2017/01/11 Javascript
Angular 4 指令快速入门教程
2017/06/07 Javascript
Three.js实现绘制字体模型示例代码
2017/09/26 Javascript
Vue.js实现列表清单的操作方法
2017/11/15 Javascript
在 Linux/Unix 中不重启 Vim 而重新加载 .vimrc 文件的流程
2018/03/21 Javascript
浅谈Vue内置component组件的应用场景
2018/03/27 Javascript
vue+axios全局添加请求头和参数操作
2020/07/24 Javascript
基于vue-simple-uploader封装文件分片上传、秒传及断点续传的全局上传插件功能
2021/02/23 Vue.js
python海龟绘图实例教程
2014/07/24 Python
Python数据类型详解(二)列表
2016/05/08 Python
Python数据结构之单链表详解
2017/09/12 Python
python3.6 实现AES加密的示例(pyCryptodome)
2018/01/10 Python
基于Python pip用国内镜像下载的方法
2018/06/12 Python
python实现桌面壁纸切换功能
2019/01/21 Python
对python生成业务报表的实例详解
2019/02/03 Python
python的help函数如何使用
2020/06/11 Python
Yves Rocher伊夫·黎雪美国官网:法国始创植物美肌1959
2019/01/09 全球购物
实习老师个人总结的自我评价
2013/09/28 职场文书
英文演讲稿
2014/05/15 职场文书
学校就业推荐信范文
2014/05/19 职场文书
小学社会实践活动总结
2014/07/03 职场文书
2014年加油站站长工作总结
2014/12/23 职场文书
Python序列化模块JSON与Pickle
2022/06/05 Python
Tomcat安装使用及部署Web项目的3种方法汇总
2022/08/14 Servers