鱼C论坛

 找回密码
 立即注册
查看: 2920|回复: 10

[作品展示] 多线程爬取全部王者高清壁纸

[复制链接]
发表于 2021-6-11 18:38:50 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 H原子 于 2021-6-11 18:43 编辑

时间:2021.06.08
作者:H原子
分析:
待爬取根网页:https://pvp.qq.com/web201605/wallpaper.shtml###
1)通过浏览器检查元素和网页源代码进行对比,猜测此网页使用了Ajax与web服务器通信,
或者使用了js对页面进行了渲染。

2)通过查找浏览器向目标服务器发出的所有请求,确定是使用了Ajax,
请求包名为:
workList_inc.cgi?activityId=2735&sVerifyCode=ABCD&…267733&iActId=2735&iModuleId=2735&_=1623155585880

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=24&iOrder=0&iSortNumClose=1&jsoncallback=jQuery17102744849148361894_1623155545802
&iAMSActivityId=51991&_everyRead=true&iTypeId=2&iFlowId=267733&iActId=2735&iModuleId=2735&_=1623155585880


响应包URL截图

响应包URL截图

**注意**
        (1)page参数:page=0表示返回第一页所需的信息,以此类推(创作这篇文章时共有25页)
        (2)jsoncallback参数:指定返回的json格式(实际就是利用该参数的值将json对象括起来),使用时删去该参数
        
3)通过分析响应信息得到:每张壁纸对应有8张图片地址,第1张为展示图片,后7张为不同分辨率的图片
由于响应对内容加密了得到如下URL:
"http%3A%2F%2Fshp%2Eqpic%2Ecn%2Fishow%2F2735122519%2F1545737998%5F%2D888937974%5F13439%5FsProdImgNo%5F6%2Ejpg%2F200"
通过urllib.parse.unquote()解码得:     
'http://shp.qpic.cn/ishow/2735122519/1545737998_-888937974_13439_sProdImgNo_6.jpg/200'

响应内容截图

响应内容截图

**注意**
        (1)这里将解码后的URL输入浏览器并不能得到预期的高分辨率图片,需要将末尾数字200改为0
        (2)还可以通过 requests.utlis.unquote():解码
                                        requests.utils.quote():编码

4)读取json格式响应内容,获取图片下载地址,下载保存。

结果展示
总计有489个主题,每个主题有8张图片,应有4912张,实际有4911,一张下载失败

总文件数截图

总文件数截图

保存形式截图

保存形式截图

源代码获取:
  1. import requests
  2. import json
  3. from urllib import parse
  4. from urllib import request
  5. import os
  6. import threading
  7. from queue import Queue


  8. #生产者:通过page_queue队列获取页面对应Ajax响应地址,提取所有页面数据,获取壁纸主题名并创建相应文件夹,并将所有的图片下载地址和保存路径加入到imgurl_queue队列中
  9. class Producer(threading.Thread):
  10.     def __init__(self,page_queue,imgurl_queue,*args,**kwargs):
  11.         self.page_queue = page_queue
  12.         self.imgurl_queue = imgurl_queue
  13.         super().__init__()
  14.         
  15.     def run(self):
  16.         headers = {
  17.                 'user-agent':'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.82 Safari/537.36'
  18.             }
  19.         while not self.page_queue.empty():
  20.             try:
  21.                 response = requests.get(self.page_queue.get(),headers = headers)
  22.             except:
  23.                 print('获取页面数据失败')
  24.             jsondata = json.loads(response.content)
  25.             datas = jsondata['List']
  26.             for data in datas:
  27.                 theme_name = parse.unquote(data['sProdName']).replace(':','').strip()#有些主题名含有英文‘:’或者空格,这类名字不能命名文件夹
  28.                 theme_name = os.path.join('images',theme_name)
  29.                 if not os.path.exists(theme_name):#当该主题文件夹未创建时创建(不加这个判断会报出'文件已存在的错误')
  30.                     os.mkdir(theme_name)
  31.                 for x in range(1,9):
  32.                     imgdict = {}
  33.                     imgdict['imgurl'] = parse.unquote(data['sProdImgNo_%d'%x])[:-3]+'0'#利用切片将200修改为0
  34.                     imgdict['imgpath'] = os.path.join(theme_name,'%d.jpg'%x)#图片命名为:x.jpg的格式
  35.                     self.imgurl_queue.put(imgdict)

  36. #消费者:通过imgurl_queue队列获取图片下载地址和保存路径,将图片下载至对应路径
  37. class Consumer(threading.Thread):
  38.     def __init__(self,imgurl_queue,*args,**kwargs):
  39.         self.imgurl_queue = imgurl_queue
  40.         super().__init__()
  41.         
  42.     def run(self):
  43.         while True:
  44.             try:
  45.                 img_obj = self.imgurl_queue.get(timeout=10)#队列为空阻塞时,等待10s,超时将触发异常,此时下载完成
  46.                 imgurl = img_obj.get('imgurl')
  47.                 imgpath = img_obj.get('imgpath')
  48.                 try:
  49.                     request.urlretrieve(imgurl,imgpath)#传递url和下载路径即可完成下载
  50.                 except:
  51.                     print('%s图片下载失败' % imgpath)
  52.             except:
  53.                 print('所有图片已下载完毕...')
  54.                 break

  55. def main():
  56.     if not os.path.exists('images'):#将所有下载的壁纸都保存在images文件夹下
  57.         os.mkdir('images')
  58.    
  59.     Ajax_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&_=1623155585880'
  60.     page_queue = Queue(30)#目前总共有25页,大小为30足够了
  61.     imgurl_queue = Queue(1000)
  62.    
  63.     #将所有页面对应的Ajax响应地址加入到page_queue队列中
  64.     for i in range(25):
  65.         page_queue.put(Ajax_url.format(i))
  66.         
  67.     #创建生产者线程   
  68.     for x in range(3):
  69.         tp = Producer(page_queue,imgurl_queue,name='生产者%d号'%x)
  70.         tp.start()

  71.     #创建消费者线程
  72.     for x in range(5):
  73.         tc = Consumer(imgurl_queue,name='消费者%d号'%x)
  74.         tc.start()
  75.         

  76.    
  77. if __name__=='__main__':
  78.     main()
复制代码

本帖被以下淘专辑推荐:

  • · python|主题: 62, 订阅: 4
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2021-6-11 23:56:26 From FishC Mobile | 显示全部楼层
贴图是个好习惯
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-6-12 09:28:29 | 显示全部楼层
贴图是个好习惯,没图没诱惑
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-6-12 19:00:44 From FishC Mobile | 显示全部楼层
阿这…,有道理
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-6-12 21:45:48 | 显示全部楼层
虽然我看不懂,但是我知道这一定很厉害!
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-6-17 21:55:39 | 显示全部楼层
分析出来才是最难的吧
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-6-17 22:48:06 | 显示全部楼层
支持一下,希望楼主做的更好,加油!
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-6-18 12:26:05 | 显示全部楼层
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2021-6-18 15:41:37 | 显示全部楼层
很酷很酷,可是看不懂源码。。。。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-6-18 21:01:58 | 显示全部楼层
亲测,可以下载,如果有显示进度情况就好了。。。

刚打开还以为没有反应。。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-6-21 11:44:05 | 显示全部楼层
努力学习中,图片和进度条下次一定,感谢大家前来捧场
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-5-19 15:36

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表