niebaohua 发表于 2019-6-16 10:11

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

niebaohua 发表于 2019-6-20 10:08

goldengod 发表于 2019-6-20 09:23
请问是如何判断 在哪里下断, 比如突然就下载 550 582 行....萌新完全不明白

要仔细观察代码, 找找相关的变量, 比如上面的skin那个地方很明显是显示皮肤,你还是不知道, 你多下几个断点, 看看先从哪开始, 然后你再慢慢去掉断点,

苏紫方璇 发表于 2019-6-16 10:37

看着图片有点乱,建议重新排版一下

丶七年 发表于 2019-6-16 10:46

大哥,谢谢你的分享~
但是排版有点看不懂过程,能不能重新拍下版,一步一步来 {:1_937:}

niebaohua 发表于 2019-6-16 12:11

苏紫方璇 发表于 2019-6-16 10:37
看着图片有点乱,建议重新排版一下

好的呢,:lol

talentmu 发表于 2019-6-16 12:13

{:301_997:}这是抓取皮肤壁纸吗?我还以为是抓取游戏皮肤文件,这么神奇,不过还是很酷

niebaohua 发表于 2019-6-16 12:18

丶七年 发表于 2019-6-16 10:46
大哥,谢谢你的分享~
但是排版有点看不懂过程,能不能重新拍下版,一步一步来

好了,看看还可以不:lol

niebaohua 发表于 2019-6-16 12:26

苏紫方璇 发表于 2019-6-16 10:37
看着图片有点乱,建议重新排版一下

删掉了,之前忘了删除附件上的,不好意思:lol

小鱼在此呵 发表于 2019-6-16 18:05

很不错,访问太快请求出错加个time.sleep好多了

黄升金; 发表于 2019-6-17 20:31

小白 想弄个成品可以私信一下吗

JIESHAO??? 发表于 2019-6-19 13:17

感谢分享,学习了
页: [1] 2
查看完整版本: js的简单分析爬取LOL皮肤