Python爬虫+二次正则解析获取TopWallpaper网站壁纸

项目说明

        之前无意间发现的壁纸网站,都是无水印且分辨率很高的壁纸,但是如果要一张一张保存显得麻烦,如果我能批量下载壁纸,就能很快筛选出自己想要保留下的壁纸。

项目结构

 

项目功能

1.两种模式

        搜索(指定关键词,建议用英文)和排行(指定日期,排序和其他属性筛选指定区间的壁纸)。

2.限制类型选择

        色色(限定类型输入0)与正常模式(限定类型输入除了0以外的任何数字)。

3.如何实现自由选择限定词的?

        答:建立了一个字典,实现了字符串之间的一个映射。核心代码如下:

# 偏好选择 升降排序默认为降序
    @staticmethod
    def preference_selection():
        print('<---Preference Selection Start--->')
        # 偏好数据字典
        categories = {'1.General': '100', '2.Anime': '010', '3.People': '001', '4.All': '111'}
        sorting = {'1.Relevance': 'relevance', '2.Random': 'random', '3.Date Added': 'date_added',
                   '4.Views': 'views', '5.Favorites': 'favorites', '6.Toplist': 'toplist', '7.Hot': 'hot'}
        topRange = {'1.Last Day': '1d', '2.Last Three Days': '3d', '3.Last Week': '1w', '4.Last Month': '1m',
                    '5.Last 3 Months': '3m',
                    '6.Last 6 Months': '6m', '7.Last Year': '1y'}

        # 字典转为列表
        categories_list = list(categories.items())
        sorting_list = list(sorting.items())
        topRange_list = list(topRange.items())
        # 获取列表长度
        categories_len = len(categories_list)
        sorting_len = len(sorting_list)
        topRange_len = len(topRange_list)

        # 获取限制选择
        print('purity: only zero.里、other.normal')
        n = int(input('请输入限制类型编号:'))
        if n == 0:
            purity_select = '001'
        else:
            purity_select = '110'

        # 获取种类选择
        print('类别: ', end='')
        for i in range(categories_len):
            if i != categories_len - 1:
                print(categories_list[i][0], '、', end='')
            else:
                print(categories_list[i][0])
        m = int(input('请输入类别编号:'))
        categories_select = categories_list[m - 1][1]

        # 获取类别选择
        print('查阅: ', end='')
        for i in range(sorting_len):
            if i != sorting_len - 1:
                print(sorting_list[i][0], '、', end='')
            else:
                print(sorting_list[i][0])
        m = int(input('请输入查阅编号:'))
        sorting_select = sorting_list[m - 1][1]

        # 获取日期选择
        print('日期范围: ', end='')
        for i in range(topRange_len):
            if i != topRange_len - 1:
                print(topRange_list[i][0], '、', end='')
            else:
                print(topRange_list[i][0])
        n = int(input('请输入日期范围编号:'))
        topRange_select = topRange_list[n - 1][1]

        print('<---Preference Selection End--->\n')
        return purity_select, categories_select, sorting_select, topRange_select

重要思路

1.前提摘要

        该网站页面会以缩略图的形式呈现壁纸,只有点击缩略图后会弹出专门的壁纸页面。

2.遇到的问题

        该网站并不是在壁纸页面直接告诉你具体下载地址,而是一个代表该图片的字符串。我们可以对字符串进行拼接得到具体地址,而问题在于图片格式无法确定,因为图片格式是在缩略图页面中告知的,如果我们直接默认.jpg/.png,就会导致格式不匹配,从而使得图片损坏,即便是修改后缀名也无济于事。

3.解决办法

        为了解决问题,我想到了使用二次正则解析(我自己命名的),什么意思呢?第一次正则解析->解析缩略图页面得到图片后缀名(是.jpg还是.png?)和壁纸展示页面地址;第二次正则解析->对第一次得到的壁纸展示页面进行解析得到关键字符串,在进行字符串拼接,在这里将第一次得到的图片后缀名拼接进去,这样我们就得到了真真正正的图片下载地址喽!核心代码如下:

    # 能够根据html页信息获取图片的格式为jpg还是png
    def get_format(self, url, word, cookies):
        # -------------解析preview页图片-------------
        # 使用 requests模块得到响应对象
        res = requests.get(url, headers=self.headers, cookies=cookies)
        # 更改编码格式
        res.encoding = "utf-8"
        # 得到html网页
        html = res.text

        # -------------正则解析-------------
        pattern = re.compile('<a class="preview".*?href="(.*?)"', re.S)
        image_link_list = pattern.findall(html)
        print('image_preview_page:\n', image_link_list)

        # --------二次正则解析获取图片格式-------
        img_format = []  # 定义一个数组来存储,总共有24个格式
        count = 1
        list = []  # 临时列表
        for url in image_link_list:
            res = requests.get(url, headers=self.headers, cookies=cookies)
            # 更改编码格式
            res.encoding = "utf-8"
            # 得到html网页
            html2 = res.text
            # 保存爬取到的html
            # self.save_html('./image/image{}.html'.format(count), html2)

            # --------解析得到正则表达式对象-------
            # r:表示原字符串,这样就可以省略掉转义字符\
            pattern = re.compile(r'<div class="scrollbox".*?<img id="wallpaper" .*?src="(.*?)".*?></div>', re.S)
            list = re.findall(pattern, html2)
            try:
                print('\rTips: 正在获取图片格式中... [{:.2f}%] {}/{}'.format(count / 24 * 100, count,
                                                                             len(image_link_list)), end='')
                # print('\nurl:', url)
                # print('待追加列表:', list)
                # print('待追加格式:', list[0][-3:])
                # print('格式列表:', img_format)
                # print('====================================================================')
                img_format.append(list[0][-3:])
            except IndexError:
                print('\nTips: (id:{})Error: list为空'.format(count))
                pass
            count += 1

            # --------爬虫睡眠---------
            # time.sleep(random.random())
            time.sleep(1)
        print()
        return image_link_list, img_format

    # 根据得到的图片格式进行拼接url
    def get_image(self, url, word, cookies):
        # 返回图片列表和图片格式列表
        image_link_list, img_format = self.get_format(url, word, cookies)
        # ------先获取到图片格式,然后才能进行url拼接------
        image_list = []
        # 拼接得到图片页
        for i in range(len(image_link_list)):  # 有些页内的图片可能不是24张,直接用图片链接列表的长度代替
            image_real_url = 'https://w.wallhaven.cc/full/{}/wallhaven-{}.{}'
            info_str = image_link_list[i][23:]
            # 现在就得到了真正存储图片的url链接,并将其依次加到image_list列表中
            image_real_url = image_real_url.format(info_str[0:2], info_str, img_format[i])
            image_list.insert(i, image_real_url)
        print('\nimage_page:\n', image_list)

        # 创建目录,用于保存图片
        directory = 'D:/Crawler/{}/'.format(word)

        # 如果目录不存在则创建,此方法常用
        if not os.path.exists(directory):
            os.makedirs(directory)

        # 添加计数
        i = 0
        for image_url in image_list:
            filename = '{}{}_{}.{}'.format(directory, word, self.count, img_format[i])
            self.save_image(image_url, filename)
            self.count += 1
            i += 1
        # 再次清空存放图片的两个列表,以便下次使用
        image_link_list = []
        image_list = []

运行结果

 

 

源码下载及视频演示

源码下载:百度网盘 请输入提取码

视频演示:[TopWallpaper_Spider v1.1]使用爬虫爬取Topwallpaper网站壁纸_哔哩哔哩_bilibili

心得

        这个项目我很早就完成了,我貌似是第一个做该网站爬虫的人,还挺自豪的。但是自己的想法和创意得不到捧场,多少有点闷闷不乐,因此我今天写了这篇博客,希望能够有更多人看见我的文章,在互联网留下自己的一些痕迹。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值