467python教程_【python】王者荣耀全英雄高清壁纸爬虫共467M(多线程)

1. 成果展示

cc340126757346ded393166a919d8d34.gif

2. 单张预览

089a3fcc2be22af7d76b4ca7eb655e48.png

3. 软件下载

win32、mac和linux用户请自行通过源码打包。

4. 壁纸下载

5. 进度打印

壁纸分辨率及序号如下:

1 > 缩略图

2 > 1024x768

3 > 1280x720

4 > 1280x1024

5 > 1440x900

6 > 1920x1080 (推荐)

7 > 1920x1200

8 > 1920x1440

请选择分辨率 (默认是6):

457/457 |████████████████████| 任务进度: 100% 已用时间: 89S 剩余时间: 0S

请按任意键继续. . .

6. 目标网址

7. 依赖模块

pip install requests

8. 完整代码

# run.py

import re, os, time, json, requests

from urllib.parse import unquote

import concurrent.futures as cf

class WangzheDownloader(object):

# 初始化

def __init__(self):

self.root = './heros/'

if not os.path.exists(self.root):

os.mkdir(self.root)

self.numberSize = 6

self.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&SearchKey=sProdName&iSortNumClose=1&iAMSActivityId=51991&_everyRead=true&iTypeId=2&iFlowId=267733&iActId=2735&iModuleId=2735&_=1607443031450'

res = requests.get(self.url.format(0)).json()

self.totalPage = int(res.get('iTotalPages'))

self.sum = int(res.get('iTotalLines'))

self.count = 0

self.startTime = time.time()

# 选择壁纸分辨率

def size(self):

print('壁纸分辨率及序号如下: ')

size_list = [

'1 > 缩略图',

'2 > 1024x768',

'3 > 1280x720',

'4 > 1280x1024',

'5 > 1440x900',

'6 > 1920x1080 (推荐)',

'7 > 1920x1200',

'8 > 1920x1440'

]

for size in size_list:

print(size)

numberSize = input('请选择分辨率 (默认是6): ')

self.numberSize = numberSize if numberSize else 6

# 获取103位英雄的名字

def name(self):

url = 'https://pvp.qq.com/web201605/js/herolist.json'

res = requests.get(url).json()

self.hero = [item['cname'] for item in res]

# 单张图片下载

def down(self, img_name, img_url):

res = requests.get(img_url)

with open(img_name, 'wb') as f:

f.write(res.content)

self.count += 1

endTime = time.time()

self.show(self.count, self.sum, endTime-self.startTime)

# 爬取每一页

def page(self, numberPage):

res = requests.get(self.url.format(numberPage)).json()

for item in res.get('List'):

# 去除图片名中的特殊字符

img_name = re.sub('[/\\:*?"<>|]', '', unquote(item['sProdName']))

# 根据英雄名建立分类文件夹

temp = re.split('[·-]', img_name)

control = True

for each in temp:

if each in self.hero:

control = False

img_dir = self.root+each

if not os.path.exists(img_dir):

os.mkdir(img_dir)

img_name = img_dir+'/'+img_name+'.jpg'

break

if control:

img_dir = self.root+'其它'

if not os.path.exists(img_dir):

os.mkdir(img_dir)

img_name = img_dir+'/'+img_name+'.jpg'

img_url = unquote(item[f'sProdImgNo_{self.numberSize}'])

img_url = img_url.replace('/200', '/0') # /0才是原图,/200都是缩略图

self.down(img_name, img_url)

# 打印进度条

def show(self, num, _sum, runTime):

barLen = 20 # 进度条的长度

perFin = num/_sum

numFin = round(barLen*perFin)

numNon = barLen-numFin

leftTime = (1-perFin)*(runTime/perFin)

print(

f"{num:0>{len(str(_sum))}}/{_sum}",

f"|{'█'*numFin}{' '*numNon}|",

f"任务进度: {perFin*100:.0f}%",

f"已用时间: {runTime:.0f}S",

f"剩余时间: {leftTime:.0f}S",

end='\r'

)

if num == _sum:

print()

# 多线程

def main(self):

self.size()

self.name()

with cf.ThreadPoolExecutor() as tp:

for page in range(self.totalPage):

tp.submit(self.page, page)

if __name__ == "__main__":

WangzheDownloader().main()

9. 代码剖析

打开目标网址,通过F12检查发现,有现有的API接口可供调用:

b625ec6e35b882e019075740e815cbf0.png

API接口里面存的就是壁纸的下载直链,也提供了图片总张数和总页数的信息:

1d3586c58a8536ccd3dc6b188943171c.png

既然有接口,我们就直接请求接口了,请求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&SearchKey=sProdName&iSortNumClose=1&jsoncallback=jQuery17107126052728750412_1607442410515&iAMSActivityId=51991&_everyRead=true&iTypeId=2&iFlowId=267733&iActId=2735&iModuleId=2735&_=1607443031450

jsoncallback=jQuery17107126052728750412_1607442410515这个参数不要,不然返回的是带前缀和后缀的jsonp数据,会影响解析。

API接口返回的json数据中,List存的是图片列表,列表长度就是请求参数中的iListNum的值,默认是20,也就是每页返回20张壁纸。

每张壁纸又有8个url,从sProdImgNo_1到sProdImgNo_8,对应于8种分辨率:

8c301706001538be5433816014362544.png

分辨率的对应关系如下:

size_list = [

'1 > 缩略图',

'2 > 1024x768',

'3 > 1280x720',

'4 > 1280x1024',

'5 > 1440x900',

'6 > 1920x1080 (推荐)',

'7 > 1920x1200',

'8 > 1920x1440'

]

你可能会问:不是还有一个sThumbURL吗?其实这个就是sProdImgNo_1,不信你可以试试。

sProdName是图片名字,无论是图片名还是链接,都需要进行url解码,在python中通过unquote解码:

from urllib.parse import unquote

解码后,把图片链接在浏览器中打开,你会发现:怎么都是缩略图?这个将图片链接后面的/200改为/0就行了。

img_url = img_url.replace('/200', '/0') # /0才是原图,/200都是缩略图

最后要说的就是图片分类问题了,每个英雄都有很多皮肤,所以我们根据英雄名建立文件夹,将同一英雄的不同皮肤都放到同一文件夹。

王者荣耀英雄名也是找了一个API接口获取的,获取方式如下:

def name(self):

url = 'https://pvp.qq.com/web201605/js/herolist.json'

res = requests.get(url).json()

self.hero = [item['cname'] for item in res]

至于这个获取英雄名的接口,也是通过F12检查英雄资料找到的:

5970de7673da48284f4162c53ba0fd33.png

接口响应信息如下,直接在浏览器中预览会乱码:

c847bb772ec7242b60b61b2e07b27538.png

把json文件下载下来查看,是正常的,其中cname就是英雄名:

74358c9624d6a609488e1ffe5dc4952d.png

10. 打包教程

10.1. 打包前的准备

先安装pipenv,在pipenv创建的虚拟环境下打包,这样打包的软件会很小。

pip install pipenv

10.2. 具体打包流程

打开cmd控制台

cd到项目路径

创建虚拟环境:pipenv install

打开虚拟环境:pipenv shell

安装依赖模块:pip install requests

安装打包工具:pip install pyinstaller

执行打包命令:pyinstaller -F -i favicon.ico run.py

10.3. 需要注意的点

run.py就是上方的完整代码,favicon.ico是软件图标,我用的是下面这个:

761ebcd5c71f62ba07b081b5c383e97b.png

下载下来是png格式,你必须转为ico格式,这里推荐一个在线转换的工具:

11. 相关推荐

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值