动态网页抓取( 移动端的英雄联盟官网英雄高清壁纸分析目标网站介绍)

优采云 发布时间: 2022-02-14 14:14

  动态网页抓取(

移动端的英雄联盟官网英雄高清壁纸分析目标网站介绍)

  

  一、背景

  随着移动终端的普及,出现了很多移动APP,应用软件也开始流行起来。最近看到英雄联盟手游上线了,感觉还行。PC端的英雄联盟可谓是一款热门游戏。不知道英雄联盟在移动端的未来是什么。墙纸。

  二、页面分析

  目标 网站:#Navi

  

  官网界面如图所示。很明显,一张小图就代表了一个英雄。我们的目的是爬取每个英雄的所有皮肤图片,全部下载并保存到本地。

  二级页面

  上面的页面称为主页面,副页面是每个英雄对应的页面。以黑暗女士为例。其二级页面如下:

  

  我们可以看到有很多小图,每张小图对应一个皮肤,通过网络查看皮肤数据接口,如下图所示:

  

  我们知道皮肤信息是以json格式作为字符串传输的,那么我们只需要找到每个英雄对应的id,找到对应的json文件,提取需要的数据就可以得到高清皮肤壁纸。

  那么这里暗黑少女的json的文件地址为:

   hero_one = 'https://game.gtimg.cn/images/lol/act/img/js/hero/1.js'

  这里的规则其实很简单。各英雄皮肤数据地址如下:

  url = 'https://game.gtimg.cn/images/lol/act/img/js/hero/{}.js'.format(id)

  所以问题是 id 的规则是什么?这里需要在首页查看英雄的id,如下:

  

  我们可以看到两个列表[0, 99], [100, 156],也就是156个英雄,但是heroId已经到了240....可以看出有一定的变化规律,不是加一个因此,要爬取所有的英雄皮肤图片,首先需要获取所有的 heroId。

  三、采集想法

  为什么要使用多线程?在这里解释一下。我们在爬取图片、视频等数据的时候,需要保存在本地,所以会用到大量的文件读写操作,也就是IO操作。想象一下,如果我们执行同步请求操作;

  然后,在第一次请求完成后,文件保存到本地后,才会发出第二次请求,效率非常低。如果使用多线程进行异步操作,效率会大大提高。

  因此,需要使用多线程或多进程,然后将这么多数据队列扔到线程池或进程池中进行处理;

  在 Python 中,multiprocessing Pool 进程池,multiprocessing.dummy 非常有用。

  multiprocessing.dummy 模块:dummy 模块是多线程的;

  多处理模块:多处理是多进程;

  multiprocessing.dummy模块和multiprocessing模块的API通用,代码切换更灵活;

  我们首先在一个测试 demo.py 文件中获取英雄 ID。我这里已经写了代码来获取英雄id的列表,可以直接在主文件中使用;

  演示.py

  url = 'https://game.gtimg.cn/images/lol/act/img/js/heroList/hero_list.js'

res = requests.get(url,headers=headers)

res = res.content.decode('utf-8')

res_dict = json.loads(res)

heros = res_dict["hero"] # 156个hero信息

idList = []

for hero in heros:

hero_id = hero["heroId"]

idList.append(hero_id)

print(idList)

  idList获取方式如下:

  idlist = [1,2,3,….,875,876,877] # 中间的英雄 id 这里不做展示

  构造网址:page = '{}.html'.format(i)

  这里的 i 表示 id,进行 url 的动态构建;

  然后我们自定义两个函数,一个用于抓取和解析页面(spider),另一个用于下载数据(download),打开线程池,使用for循环构造一个url,存放英雄皮肤的json数据,它作为url Queue存储在一个列表中,使用pool.map()方法执行蜘蛛(爬虫)功能;

  def map(self, fn, *iterables, timeout=None, chunksize=1):

"""Returns an iterator equivalent to map(fn, iter)”“”

# 这里我们的使用是:pool.map(spider,page) # spider:爬虫函数;page:url队列

  功能:提取列表中的每一个元素作为函数的参数,一个一个地创建一个进程,放入进程池中;

  参数1:要执行的函数;

  参数2:迭代器,将迭代器中的数字作为参数依次传递给函数;

  json数据解析

  

  这里我们解析一下黑暗女神皮肤的json文件。我们需要获取的内容是1.name,2.skin_name,3.mainImg,因为我们发现heroName是一样的,所以以英雄名作为皮肤文件夹名英雄,便于查看和保存;

  item = {}

item['name'] = hero["heroName"]

item['skin_name'] = hero["name"]

if hero["mainImg"] == '':

continue

item['imgLink'] = hero["mainImg"]

  有一个注意事项:

  有的 mainImg 标签是空的,所以我们需要跳过,否则如果是空的链接,请求时会报错;

  四、数据采集

  导入相关第三方库

  import requests # 请求

from multiprocessing.dummy import Pool as ThreadPool # 并发

import time # 效率

import os # 文件操作

import json # 解析

  页面数据分析

  def spider(url):

res = requests.get(url, headers=headers)

result = res.content.decode('utf-8')

res_dict = json.loads(result)

skins = res_dict["skins"] # 15个hero信息

print(len(skins))

for index,hero in enumerate(skins): # 这里使用到enumerate获取下标,以便文件图片命名;

item = {} # 字典对象

item['name'] = hero["heroName"]

item['skin_name'] = hero["name"]

if hero["mainImg"] == '':

continue

item['imgLink'] = hero["mainImg"]

print(item)

download(index+1,item)

  下载 下载图片

  def download(index,contdict):

name = contdict['name']

path = "皮肤/" + name

if not os.path.exists(path):

os.makedirs(path)

content = requests.get(contdict['imgLink'], headers=headers).content

with open('./皮肤/' + name + '/' + contdict['skin_name'] + str(index) + '.jpg', 'wb') as f:

f.write(content)

  这里我们使用 OS 模块来创建一个文件夹。前面我们提到过,每个英雄的 heroName 的值都是一样的,所以我们可以创建一个文件夹并命名,方便皮肤保存(分类),然后这里就是图片文件的路径。需要小心,少一个斜线会报错。

  main() 主函数

  def main():

pool = ThreadPool(6)

page = []

for i in range(1,21):

newpage = 'https://game.gtimg.cn/images/lol/act/img/js/hero/{}.js'.format(i)

print(newpage)

page.append(newpage)

result = pool.map(spider, page)

pool.close()

pool.join()

end = time.time()

  操作说明:

  在 main 函数中,我们更喜欢创建六个线程池;

  通过for循环动态构建20个url,我们试一试,20个英雄皮肤,如果全部爬取,可以遍历之前的idList,然后动态构建url;

  使用map()函数对线程池中的url进行数据解析和存储操作;

  当线程池关闭时,线程池并没有关闭,而是状态变为不能再插入元素的状态;

  五、程序运行

  if __name__ == '__main__':

main()

  结果如下:

  

  当然,这里只抓取了部分图片,总共爬取了200+张图片,总体还可以。

  六、总结

  这次我们使用多线程抓取英雄联盟官网的英雄皮肤高清壁纸。因为图片中涉及到IO操作,所以我们使用并发的方式来大大提高程序的执行效率。

  当然,爬虫也只是尝过而已。这一次,我爬取了20个英雄的皮肤图。有兴趣的朋友可以爬取所有的皮肤,只需要将遍历的元素改成之前的idlist即可。

  原文链接:

0 个评论

要回复文章请先登录注册


官方客服QQ群

微信人工客服

QQ人工客服


线