Python零基础之爬取王者荣耀官方网站高清壁纸(普通版)

目标:

  • 1.下载王者荣耀网站游戏壁纸的高清壁纸
  • 2.把同一个名称的壁纸放到同一个文件夹

分析过程:

1. 确定目标url

  • 访问https://pvp.qq.com/web201605/wallpaper.shtml

  • 发现图片地址并不在网页html源码中,检查浏览器,分析network。发现目标url有可能是:

    • https://apps.game.qq.com/cgi-bin/ams/module/ishow/V1.0/query/workList_inc.cgi?activityId=2735&sVerifyCode=ABCD&sDataType=JSON&iListNum=20&totalpage=0&page=0&iOrder=0&iSortNumClose=1&jsoncallback=jQuery17105576461901361978_1597489598391&iAMSActivityId=51991&everyRead=true&iTypeId=2&iFlowId=267733&iActId=2735&iModuleId=2735&=1597489758464
  • 删掉&jsoncallback回调函数部分的内容,此时可以返回json数据

  • 所以目标url就是这个

    • https://apps.game.qq.com/cgi-bin/ams/module/ishow/V1.0/query/workList_inc.cgi?activityId=2735&sVerifyCode=ABCD&sDataType=JSON&iListNum=20&totalpage=0&page=0&iOrder=0&iSortNumClose=1&iAMSActivityId=51991&everyRead=true&iTypeId=2&iFlowId=267733&iActId=2735&iModuleId=2735&=1597489758464
  • 通过json.cn格式化代码,发现其中含有jpg的地址信息

  • 如:

    • “http%3A%2F%2Fshp%2Eqpic%2Ecn%2Fishow%2F2735081209%2F1597196301%5F84828260%5F17286%5FsProdImgNo%5F1%2Ejpg%2F200”
  • http地址经过了编码,需要解码还原jpg地址

  • 同时发现’sProdName’对应的为图片名称,也需要解码

2. 解决url解析问题

  • 尝试利用urllib里边的parse.unquote解码地址
from urllib import parse

base_url = "http%3A%2F%2Fshp%2Eqpic%2Ecn%2Fishow%2F2735081209%2F1597196301%5F84828260%5F17286%5FsProdImgNo%5F1%2Ejpg%2F200"

# 解析url
url = parse.unquote(base_url,encoding='utf-8')

print(url)
  • 输出为:

http://shp.qpic.cn/ishow/2735081209/1597196301_84828260_17286_sProdImgNo_1.jpg/200

3. 图片下载解析

  • 注意到/200都是缩略图,大图需要改成/0

http://shp.qpic.cn/ishow/2735081209/1597196301_84828260_17286_sProdImgNo_1.jpg/0

4. 多页面的处理

  • 爬取多页需要修改url的&page参数,第一页默认0,以此类推

代码示例

import requests
from urllib import parse
import os
from urllib import request


# 添加请求头U-A和referer,避免反爬
headers = {
    'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36',
    'referer': 'https://pvp.qq.com/web201605/wallpaper.shtml'}

# 定义一个函数来获取每张图片的url
def extract_images(data):
    image_urls = []
    for x in range(1, 9):
        # 每组图片共8张,通过这种方式获取一组照片的所有地址
        # 通过.unquote解码地址,并且替代末尾的'200'为'0'
        image_url = parse.unquote(data['sProdImgNo_%d' % x]).replace('/200', '/0')
        image_urls.append(image_url)

    return image_urls

def page_url_list(base_url):

    page_urls = []
    for i in range(23):
        base_page_url = base_url.format(
            str(i))
        page_urls.append(base_page_url)

    # print(page_urls)
    return page_urls

def main():
    # 确认页面url地址
    base_url = 'https://apps.game.qq.com/cgi-bin/ams/module/ishow/V1.0/query/workList_inc.cgi?activityId=2735&sVerifyCode=ABCD&sDataType=JSON&iListNum=20&totalpage=0&page={}&iOrder=0&iSortNumClose=1&iAMSActivityId=51991&_everyRead=true&iTypeId=2&iFlowId=267733&iActId=2735&iModuleId=2735&_=1597489758464k'

    page_urls = page_url_list(base_url)

    for page_url in page_urls:

        resp = requests.get(page_url, headers=headers)

        # 获取的是一个json类型的字符串
        # print(resp.text)
        # 可以通过.json()直接处理,替代json.loads()
        # print(type(resp.json()),resp.json())
        # 返回的是一个字典,可以通过K-V取值
        result = resp.json()

        datas = result['List']

        for data in datas:
            # 通过图片地址处理函数处理列表数据
            image_urls = extract_images(data)

            # 获取图片的名称,由于要按照文件名创建目录,所以要对空格进行处理
            name = parse.unquote(data['sProdName']).strip()
            # print('-' * 70)
            # print(name)
            # print('-' * 70)
            # print(image_urls)
            # print('-' * 70)

            # 先创建一个用来存放image的主目录
            # 当文件夹不存在时创建,当存在时跳过
            if os.path.exists('./image') == False:
                os.mkdir('image')
            else:
                pass
            # 创建一个文件夹./image/name/
            # 创建路径
            dirpath = os.path.join('image',name)
            # 按照路径创建文件夹
            os.mkdir(dirpath)

            # 下载图片
            # 注意index索引值写前边
            for index,image_url in enumerate(image_urls):

                # request.urlretrieve(,)传参地址和路径,就可以保存图片
                # 每个图片的地址是不同的,按照保存路径,图片名称,和索引+1以及文件类型名称的路径保存
                request.urlretrieve(image_url,os.path.join(dirpath,name+'%d.jpg' % (index + 1)))
                print(name,'%s下载成功' % image_url)

if __name__ == '__main__':
    main()

需要注意的问题:

  1. url分析时,找到对应url后,需要根据反馈结果在www.json.cn查看是否能够正常解析
  2. 发现图片地址格式和图面名称不正常,可以通过urllib.parse.unquote()解码成正常数据
  3. 图片地址修改时,不能只把200改成0,要防止url地址中出现200,所以改/200为/0出错的可能性会更小一点。当然也可以通过re正则从后端匹配修改,会更为稳妥
  4. 文件名中如果有空格,创建文件夹会报错,所以要用strip()处理; 文件名可能还有全角字符等,也需要进行处理(代码中未写全角字符的处理)
  5. 文件路径可以通过引入os,利用os.path.join()链接路径
  6. 文件夹创建使用os,mkdir(),可以利用os.path.exists()判断文件夹是否存在,如果不存在再创建,可以避免文件夹已存在的错误
  7. 多页的数据获取可以尝试修改&page=的数值
  8. 图片下载使用urllib.request.urlretrieve()比较简介只需要传入url和存储地址(含文件名)就可以了
  9. 图片保存的文件名可以利用enumerate()里的index值作为后缀添加;注意不要遗漏文件类型(本文为.jpg)
    10.存储过程中,还要注意,如果url中有多个地址重复,保存时会提示文件已存在时无法创建文件等错误,还可以加入异常处理,或者文件是否存在的判断等(代码示例中不含该部分代码)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

kingx3

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值