Python爬取动态加载的壁纸网站(高清壁纸福利)

“静态网页"和"动态网页”

"静态网页":一次性加载,爬虫可以爬到全部信息。关于静态网页的Demo
“动态网页”:分多次加载,爬虫只能爬取部分信息(无法直接执行JavaScript代码带来的问题)。

接下来让我们用selenium开始解析动态网页吧

我们需要的工具selenium

selenium是什么?有啥用?我们用了它能解决什么问题?

selenium最初是一个自动化测试工具,而爬虫中使用它主要是为了解决requests无法直接执行JavaScript代码的问题。
selenium本质是通过驱动浏览器,完全模拟浏览器的操作,比如跳转、输入、点击、下拉等,来拿到网页渲染之后的结果,可支持多种浏览器。

selenium的下载和安装

提供两种方法
1、pip xxx
2、打开pycharm等软件,自行搜索库名下载。

selenium对应浏览器插件的下载和安装

下方是selenium支持的浏览器

Chrome
Firefox
PhantomJS
Safari
Edge

根据自己的浏览器类别去下载对应的浏览器插件,接下来用Chrome做例子。

1、查看自己浏览器的版本
打开浏览器,在地址栏输入chrome://version/

2.下载对应的插件
Chrome插件下载地址
在这里插入图片描述
找到和自己浏览器版本最接近的版本,点击进去,点击对应操作系统的链接进行下载。

Hello Word~(测试环境是否成功)

from selenium import webdriver

driver = webdriver.Chrome ('你下载的浏览器插件的路径')

如果弹出Chrome窗口,恭喜你。
如果报错,请你检查一下上面步骤或者百度

壁纸网址介绍

超级好看的的壁纸网站
在这里插入图片描述
简单说一下这个网站的特点
1、下拉式加载壁纸
2、JS加载壁纸
3、每个壁纸都有很多版本(4K、2K等)

源码

import os
import random
import ssl
import time

ssl._create_default_https_context = ssl._create_unverified_context

from bs4 import BeautifulSoup
import urllib.request

''' 
在这说明一下  为什么要用selenium
1、有些页面是异步加载返回的,它不是直接返回请求的数据,爬虫只能抓取到最开始的部分数据(空壳数据)后面的数据是由Javascript异步加载进来的
2、爬虫不能解决js加载的问题,所以我们要用selenium
3、我们需要利用selenium抓取js加载的数据(壁纸)
'''

from selenium import webdriver  # 调用浏览器做操作
from selenium.webdriver.common.by import By  # 按照什么方式查找,By.ID,By.CSS_SELECTOR
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait  # 等待页面加载某些元素  js加载

# 指定Chrome驱动的位置
chromePath = '/Users/apple/Downloads/Chrome下载/chromedriver'
# 壁纸保存的路径
savePath = '/Users/apple/Downloads/desktopPictureTest'


# 下该函数为载壁纸  pageCode参数:选择壁纸的种类 maxSlideNumber参数:下拉的次数
def downloadPicture(pageCode, maxSlideNumber):
    # 打开Chrome浏览器
    browser = webdriver.Chrome(chromePath)
    print('打开Chrome中...')
    # 由于这个网站下拉加载更多的壁纸  所以 初始化下拉次数
    slideNumber = 1
    # 存放爬取到的图片href
    DownloadList = []
    # 下载失败的图片href
    noDownloadList = []
    try:
        # 跳转到壁纸页面
        browser.get('https://ss.netnr.com/wallpaper' + pageCode)
        # 我们需要的壁纸放在class名为'row'的div中  我们需要等这个div加载好  我们再抓数据
        while True:
            try:
                # 有时候服务器和网会有点小问题,所以给row10秒加载  如果加载大于10秒 刷新网页 重新开始
                wait = WebDriverWait(browser, 10)
                # 等到CLASS_NAME为raw的div加载完毕,最多等10秒
                wait.until(EC.presence_of_element_located((By.CLASS_NAME, 'row')))
                # 如果达到了下拉次数,则跳出循环
                if slideNumber > maxSlideNumber:
                    break
                # 没达到下拉次数  +1继续循环
                slideNumber = slideNumber + 1
                # 如果div加载成功我们需要更多的壁纸,所以下滑到底。
                print('下拉中....')
                browser.execute_script('window.scrollTo(0,document.body.scrollHeight)')
                # 睡眠5秒再次下拉  可以充分展现下拉的用处
                time.sleep(5)
            # 如果加载大于10秒 刷新网页 重新开始
            except:
                # 刷新网页
                print('刷新网页...')
                browser.refresh()

        # 此时的网页就是下拉n次后的网页  蕴含着好多壁纸

        # 处理网页内容
        soup = BeautifulSoup(browser.page_source, "html.parser")
        # 抓取div
        rows = soup.findAll(class_='list-group')

        for i in rows:
            # 抓取a标签
            aHref = i.findAll('a')

            for i in aHref:
                # 抓取href(下载地址)
                src = i.get('href')
                # 把壁纸的href放入列表
                DownloadList.append(src)
                # 为什么要break呢  因为此网站提供好几个版本的壁纸  我们只需要第一个(画质最好的版本)
                break

        # 此时开始下载壁纸

        # 如果文件夹不存在则创建
        if not os.path.exists(savePath):
            os.makedirs(savePath)

        # 所有的图片处理完成(失败或者成功)  才可以结束
        # 可能因为网络和机器的问题,下载会失败,所以采用循环机制
        print('\033[0;36m')
        print('共抓取到' + str(DownloadList.__len__()) + '张壁纸')
        print('\033[0m')
        print(
            '<=====================================================================================================================================>')
        # 无论处理成功还是失败,列表的数据处理完才能结束
        while DownloadList.__len__()>0:
            # 遍历列表  逐个下载壁纸
            for i in DownloadList:
                # 壁纸名称
                name = i.split('/')[-1]

                # 避免名称重复  采用随机数
                saveFile = savePath + "/" + 'qianFuXin' + str(random.randint(0, 9)) + str(random.randint(0, 9)) + \
                           str(random.randint(0, 9)) + str(random.randint(0, 9)) + name
                if os.path.exists(saveFile):
                    print(saveFile + '已经存在')
                    exit(0)
                try:
                    urllib.request.urlretrieve(i, saveFile)
                    # 下载成功就移除列表
                    DownloadList.remove(i)
                    print('处理成功!该文件为:' + saveFile)
                    print('还剩' + str(DownloadList.__len__()) + '张')
                    print(
                        '<=====================================================================================================================================>')
                except:
                    # 下载失败就等下次继续下载

                    noDownloadList.append(i)
                    print("\033[37;41m处理失败\033[0m")
                    DownloadList.remove(i)
                    print('还剩' + str(DownloadList.__len__()) + '张')
                    print(
                        '<=====================================================================================================================================>')

        # 输出未完成的href  人工处理
        print("\033[37;41m未完成的图片href如下\033[0m")
        for i in noDownloadList:
            print(i)
    finally:
        # 关闭Chrome页面
        browser.close()


def initChoose():
    pictureKindAndCode = {'最新壁纸': '#', '4K专区': '#36', '美女模特': '#6',
                          '爱情美图': '#30', '风景大片': '#9',
                          '小清新': '#15', '动漫卡通': '#26',
                          '明星风尚': '#11', '萌宠动物': '#14',
                          '游戏壁纸': '#5', '汽车天下': '#12',
                          '炫酷时尚': '#10', '日历壁纸': '#29',
                          '影视剧照': '#7', '节日美图': '#13',
                          '军事天地': '#22', '劲爆体育': '#16',
                          'baby秀': '#18', '文字控': '#35'}
    pictureKindAndNumber = {}
    number = 1
    print(
        '<=====================================================================================================================================>')
    for i in pictureKindAndCode:
        print(str(number) + '、' + i)
        pictureKindAndNumber[str(number)] = i
        number = number + 1
    print(
        '<=====================================================================================================================================>')
    userChoose = input("\033[1;30;47m输入壁纸编号(范围:1-19):\033[0m")

    # 正则表达式判断输入是不是在数字范围内
    # matches  只要有一个满足就行  11 是满足[1-9]的  因为1满足了[1-9]
    # 做个标记
    # 改用isdigit
    if userChoose.isdigit() and 20 > int(userChoose) > 0:
        pageCode = pictureKindAndCode[pictureKindAndNumber[userChoose]]
    else:
        print("\033[37;41m请输入1-19之间的数字\033[0m")
        exit(0)
    maxSlideNumber = input("\033[1;30;47m输入下拉次数(范围1-99):\033[0m")
    # 正则表达式判断输入是不是在数字范围内
    # matches  只要有一个满足就行
    if userChoose.isdigit() and 100 > int(userChoose) > 0:
        pass
    else:
        print("\033[37;41m请输入1-99之间的数字\033[0m")
        exit(0)
    return pageCode, maxSlideNumber


if __name__ == '__main__':
    print('\033[0;36m')
    print('Default ChromePath\t==>\t' + chromePath)
    print('Default SavePicturePath\t==>\t' + savePath)
    print('\033[0m')
    # 确定路径是都正确
    defaultPathChoose = input('请查看上方路径是否正确,如果正确输入1继续执行程序,否则输入任意字符退出程序:')
    if defaultPathChoose.__eq__('1'):
        pass
    else:
        exit(0)
    # 初始化选择
    pageCode, maxSlideNumber = initChoose()
    print('准备下载壁纸.....')
    # 下载壁纸
    downloadPicture(pageCode, int(maxSlideNumber))
    #结束下载
    print('\033[0;36m')
    print('下载结束')
    print('\033[0m')

猜你喜欢

转载自blog.csdn.net/Mr_Qian_Ives/article/details/107228526
今日推荐