js的简单分析爬取LOL皮肤
本帖最后由 niebaohua 于 2019-6-16 12:33 编辑爬这个网站之前没去网上找,自己研究了几个小时,才搞定的。
写完之后,我去网上看看别人的思路,都是一样的思路。。。。
而且还是几年前的帖子。。。
没正式学过浏览器的调试,如有错误,请纠正,万分感谢。
对于这个网站,我们按照平常的爬取方式发现什么也获取不到, 也找不到有用的api
网页使用动态获取的
相关知识:
Step over next function call【单步跳过】 : 会跳到下一个断点
Step into next function call【单步进入】 : 会进入函数内部调试
Step out of current function 【单步跳出】: 会跳出当前这个断点的函数 LOL官网英雄列表
打开多个皮肤图片链接:https://ossweb-img.qq.com/images/lol/web201310/skin/big266003.jpg
266003
发现每个图片只有这几个数字是变动的, 其他都是固定的,所以只要找到这些id就行了
在英雄列表审查元素,查看每个英雄的超链接
发现每个英雄 后面也是有一个id的,
那来调试一下,看看这些英雄列表怎么生成的 先点击Source
打上断点之后 F5刷新页面
点这里
我们点几次之后发现会到这里,加载这个js,我们直接复制链接,用浏览器直接打开,看看内容是什么
我们会发现所有的英雄的资料都在data中,可是这里没有我们要的那几个随机数字的id
这里我们可以取的数据有title或者name作为我们要创建的文件夹还有英雄的id
关闭调试
我们随便点击一个英雄,
进入皮肤界面https://lol.qq.com/data/info-defail.shtml?id=Ahri我们分析网页之后发现,
只有这个id是变的,需要用到刚刚的那个js https://lol.qq.com/biz/hero/champion.js
用js里面data中的英雄id 现在我们处于英雄皮肤的界面,进行调试和刚刚一样
在550行,582行打上断点,
会首先来到这里,传进去一个英雄的id
这个时候继续上一步的点击会到这里
我们用一个英雄id,拼接这个完整的js,然后用浏览器打开例如: https://lol.qq.com/biz/hero/Ahri.js
这里的skins,就是我们的皮肤列表,id为皮肤的id, name为皮肤的名字,default为默认皮肤这样就完成了
爬虫思路:
先提取champion.js, 获取所有英雄的id和名字,我们通过名字创建文件夹然后通过英雄id拼接js,
提取英雄.js中skins, 获取皮肤的id,和皮肤的name最后下载
# -*- encoding: utf-8 -*-
"""
@file : 英雄联盟skins.py
@Time : 2019/6/12 0012 下午 17:53
@AuThor: 年少、
@Software: PyCharm
"""
import requests
import re
import json
import os
import pprint
class LolSkins(object):
def __init__(self):
self.js_url = "http://lol.qq.com/biz/hero/%s.js"
# self.hero_url = "https://lol.qq.com/web201310/js/herovideo.js"
self.hero_url = "https://lol.qq.com/biz/hero/champion.js"
self.pic_url = "http://ossweb-img.qq.com/images/lol/web201310/skin/big%s.jpg"
self.headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.80 Safari/537.36"
}
self.hero_list = []
self.json_datas = None
self.path ="./lol"
def get_hero_data(self):
response = requests.get(self.hero_url, headers=self.headers).text
# print(response)
regex = re.compile(r'\"data\":(.*\W)+')
datas = re.findall(regex, response)
a = "{\"data\":" + datas[:-1]
a = json.loads(a)['data']
self.json_datas = json.loads(str(list(a.values())).replace("'", "\""))
# pprint.pprint(self.json_datas)
# for i in range(0,len(datas), 2):
# self.hero_list.append("{" + "".join(datas)[:-1] + "}")
def download(self, id, name, path):
res = requests.get(self.pic_url% id, headers=self.headers)
if name == "default":
name = "默认皮肤%s" % id
name = name.replace("/", "")
with open(path + name + ".jpg", 'wb') as f:
f.write(res.content)
print(name + "-----------------下载完成")
def get_heroPic_id(self):
# self.json_datas = json.loads(("{ \"datas\":" + str(self.hero_list) + "}").replace("'", "").replace("\\", ""))
# print(len(self.json_datas['datas']))
self.mkdir()
for data in self.json_datas:
url = self.js_url % data['id']
res = requests.get(url, headers=self.headers).text
regex = re.compile('"data"(.*\W)+')
datas = '{"datas"' + re.findall(regex, res)[:-1]
datas = json.loads(datas)
for pic_data in datas['datas']['skins']:
self.download(pic_data['id'], pic_data['name'], self.path + "/%s/" % data['name'])
def mkdir(self):
if not os.path.exists(self.path):
os.mkdir(self.path)
for dir in self.json_datas:
if not os.path.exists(self.path + "/%s" %dir['name']):
os.mkdir(self.path + "/%s" % dir['name'])
else:
pass
if __name__ == '__main__':
lol = LolSkins()
lol.get_hero_data()
lol.get_heroPic_id()
正则表达式不擅长, 你们可以补充一下,让代码更简单{:301_997:}第一次发的那么长的帖子
壁纸:链接:https://pan.baidu.com/s/118DUlXpGBdv2TD0dnyqbCw 密码:ocp5
goldengod 发表于 2019-6-20 09:23
请问是如何判断 在哪里下断, 比如突然就下载 550 582 行....萌新完全不明白
要仔细观察代码, 找找相关的变量, 比如上面的skin那个地方很明显是显示皮肤,你还是不知道, 你多下几个断点, 看看先从哪开始, 然后你再慢慢去掉断点, 看着图片有点乱,建议重新排版一下 大哥,谢谢你的分享~
但是排版有点看不懂过程,能不能重新拍下版,一步一步来 {:1_937:} 苏紫方璇 发表于 2019-6-16 10:37
看着图片有点乱,建议重新排版一下
好的呢,:lol {:301_997:}这是抓取皮肤壁纸吗?我还以为是抓取游戏皮肤文件,这么神奇,不过还是很酷 丶七年 发表于 2019-6-16 10:46
大哥,谢谢你的分享~
但是排版有点看不懂过程,能不能重新拍下版,一步一步来
好了,看看还可以不:lol 苏紫方璇 发表于 2019-6-16 10:37
看着图片有点乱,建议重新排版一下
删掉了,之前忘了删除附件上的,不好意思:lol 很不错,访问太快请求出错加个time.sleep好多了 小白 想弄个成品可以私信一下吗 感谢分享,学习了
页:
[1]
2