自制网页爬取工具(扒图,扒取网页神器)

版权声明:本文为博主原创文章,请随意转载。 https://blog.csdn.net/a_hui_tai_lang/article/details/83040522

每每看到一些漂亮的网页就忍不住想把它下载下来,查看的HTML源码、调试、改造。因此就根据自己的想法制作了一个扒取网页到本地python爬虫代码,爬取一般的网页,效果还行,真是前端,UI必备神器。先看看我爬取到本地的网页,显示效果如下:

在这里插入图片描述
在这里插入图片描述
代码如下:

#coding=utf-8
import ssl
import urllib
import urllib2
import os
from lxml import etree
import traceback

def mkdir(path):
    '''
    可以创建多级目录
    :param path:
    :return:
    '''
    path = path.strip().rstrip("\\")
    isExists = os.path.exists(path)
    if not isExists:
        os.makedirs(path)
        print path + ' 创建成功'
        return True
    else:
        print path + ' 目录已存在'
        return False

class staticSpider():
    '''
    静态页面的爬取类
    默认图片放在img/下,js放在scripts/下,css放在css/下
    '''
    def __init__(self,baseUrl, url,basePath):
        '''
        目录必须带'/',
        baseUrl是指http://域名/,baseUrl必须以'/'结尾
        url是指需要下载的页面,如http://域名/xx/yy.html
        basePath是指要保存到哪个目录下面,必须以'/'结尾
        '''
        self.baseUrl = baseUrl
        self.basePath = basePath
        self.url=url
        self.html=''
        self.mode=0
        self.urlDic={}

    def getAbsoluteUrl(self,url):
        '''
        一个网页url可能是相对路径
        这个方法可以根据url来获取一个可以访问的url
        :param url:
        :return:
        '''
        if url.startswith('/'):
            return urllib.basejoin(self.baseUrl,url)
        else:
            return urllib.basejoin(self.url,url)

    def getSourceCode(self, url):
        '''
        根据url获取网页源码,即HTML
        :param url:
        :return:
        '''
        headers = {
            "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_0) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.56 Safari/535.11"}
        context = ssl._create_unverified_context()
        request = urllib2.Request(url, headers=headers)
        print url
        return urllib2.urlopen(request,context=context).read()

    def writePage(self, html, filename, mode='w'):
        """
            作用:将html内容写入到本地
            html:服务器相应文件内容
        """
        print "正在保存 " + filename
        # 文件写入
        with open(filename, mode) as f:
            f.write(html)
        print "-" * 30

    def writePicture(self, url, filename=''):
        '''
        根据url获取图片并保存到本地
        :param url:
        :param filename:
        :return:
        '''
        if filename == '':
            filename = self.getFileName(url)
        abUrl=self.getAbsoluteUrl(url)
        pic=self.getSourceCode(abUrl)
        self.writePage(pic,  filename, 'wb')

    def downloadUrl(self, url, filename='',mode='w'):
        '''
        直接根据url下载HTML,保存到本地
        :param url:
        :param filename:
        :param mode:
        :return:
        '''
        if filename == '':
            filename = self.getFileName(url)
        abUrl=self.getAbsoluteUrl(url)
        try:
            pic=self.getSourceCode(abUrl)
            self.writePage(pic,  filename, mode)
        except Exception:
            traceback.print_exc()

   
    def getFileName(self,url):
        '''
        给个url获取对应的保存到本地文件名
        :param url:
        :return:
        '''
        url=url.rstrip('\\').rstrip('/')
        index = url.rfind('\\')
        index1 = url.rfind('/')
        if index<index1:
            index=index1
        filename = url[index+1:]
        if filename=='':
            filename='index.html'
        return filename

    def parseUrl(self,url):
        self.html = self.getSourceCode(url)
        return self.html

    def downloadByType(self, savePath, getList, url='', mode='w'):
        '''
        这个是一个比较灵活的方法,可以传一个getList方法获取一系列需要爬取的url,
        然后将url对应的源码或者文件爬取,下载到本地
        :param savePath:
        :param getList: 这是一个方法,需要传一个参数(HTML源码),返回一个url列表,比如:urlList = getList(html)
        :param url:
        :param mode:
        :return:
        '''
        if url == '':
            html = self.html
        else:
            html = self.getSourceCode(url)
        urlList = getList(html)
        print 'downloadByType', urlList
        for eUrl in urlList:
            filename = self.getFileName(eUrl)
            self.html = self.html.replace(eUrl, savePath[len(self.basePath):] + filename)
            print self.getAbsoluteUrl(eUrl)
            try:
                css = self.getSourceCode(self.getAbsoluteUrl(eUrl))
                self.writePage(css, savePath + filename, mode)
            except Exception:
                traceback.print_exc()

    def downloadPicture(self, url=''):
        '''
        下载页面所需要的图片,保存到img/下
        :param url:
        :return:
        '''
        basePath = self.basePath.rstrip("/")
        def getPicList(html):
            selector = etree.HTML(self.html)
            imgList = selector.xpath("//img/@src")
            imgList2 = selector.xpath("//link[contains(@href,'.')]/@href")
            urlSet=set(imgList+imgList2)
            return [img for img in urlSet if (img.endswith('.png') or img.endswith('.jpg') or img.endswith('.jpeg') or img.endswith('.gif') or img.endswith('.ico')) ]
        mkdir(basePath + 'img/')
        self.downloadByType(self.basePath + 'img/', getPicList, url=url,mode='wb')


    def downloadJs(self, url='', filename=''):
        '''
        下载页面所需要的图片,保存到script/下
        :param url:
        :param filename:
        :return:
        '''
        basePath = self.basePath.rstrip("/")
        def getCssList(html):
            selector = etree.HTML(self.html)
            jsList=selector.xpath("//script[contains(@src,'.js')]/@src")
            return [i for i in jsList if i.endswith('.js')]
        mkdir(basePath + 'script/')
        self.downloadByType(self.basePath + 'script/', getCssList, url=url)

    def downloadCss(self, url='', filename=''):
        '''
        下载页面所需要的css,保存到css/下
        :param url:
        :param filename:
        :return:
        '''
        basePath = self.basePath.rstrip("/")
        def getCssList(html):
            selector = etree.HTML(self.html)
            cssList = selector.xpath("//link[contains(@href,'.css')]/@href")
            return [i for i in cssList if i.endswith('.css')]
        mkdir(basePath+'css/')
        self.downloadByType(self.basePath+'css/',getCssList,url=url)

    def download(self,url,filename='index.html'):
        '''
        下载静态页面,以及相关的css,js,默认保存的页面文件名为index.html
        :param url:
        :param filename:
        :return:
        '''
        self.parseUrl(self.url)
        self.downloadCss(url)
        self.downloadJs(url)
        self.downloadPicture(url)
        self.writePage(self.html,self.basePath+filename)



url='https://www.bxwx.la/b/53/53693/'
spider=staticSpider('https://www.bxwx.la/',url,'D:\\AAA\\Aspider\\bxwx2\\')
spider.download(url)

代码主要用来爬取单个静态页面,有些地方我希望写的灵活点,有点函数式编程的味道,这个类也是可以扩展的,可以通过继承这个类改写其中的一些方法,实现一个定制的页面爬取。
download()方法是一个通用的下载,会把网页,css,js都下载下来,如果还有一些比较特殊的css或js没有下载下来,可以使用downloadUrl单独下载。

代码放在GitHub上,python-learning
以上具体代码在目录crawler/static_web/web_common.py
我的GitHub
我建了一个大数据的学习交流群
QQ:2541692705
Q群:882855741
邮箱:[email protected]
微信公众号:程序国度
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/a_hui_tai_lang/article/details/83040522