其他分享
首页 > 其他分享> > 数据藏在json文件中,如何爬取---以王者荣耀官网为例

数据藏在json文件中,如何爬取---以王者荣耀官网为例

作者:互联网

此前写了一个爬虫基础案例---爬取王者荣耀英雄与技能介绍

python爬虫------王者荣耀英雄及技能爬取并保存信息到excelicon-default.png?t=L892https://blog.csdn.net/knighthood2001/article/details/119514336?spm=1001.2014.3001.5501眼尖的人能发现,爬到的数据不完全(英雄缺少)

import requests
import re
import pandas as pd

base_url = 'https://pvp.qq.com/web201605/herolist.shtml'
headers = {
    'referer': 'https://pvp.qq.com/',
    'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'
}
response = requests.get(base_url, headers=headers)
response.encoding = 'gbk'
r = response.text
# print(response.text)
# 输出的是网页的全部源代码

# 由于英雄的网址为无序,故使用re
wangzhi = re.compile(r'<a href="herodetail/(\d*).shtml" target="_blank"')
hero_xuhao_list = re.findall(wangzhi, r)
# print(hero_xuhao_list)
df = []
# 标题栏
columns = ['英雄', '被动', '技能1', '技能2', '技能3', '技能4']
for id in hero_xuhao_list:
    detail_url = 'https://pvp.qq.com/web201605/herodetail/{}.shtml'.format(id)
    # print(detail_url)
    response1 = requests.get(detail_url, headers=headers)
    response1.encoding = 'gbk'
    # print(response1.text) # 获得具体网址的全部源代码
    names = re.compile('<label>(.*?)</label>')
    name = names.findall(response1.text)[0]
    # 没有这个[0],会使得excel中的数据是['云中君'],即中文名外面还有引号和[]
    skills = re.compile('<p class="skill-desc">(.*?)</p>', re.S)
    skill = skills.findall(response1.text)
    # print(skill)
    beidong = skill[0]
    # print(beidong)
    jineng1 = skill[1]
    jineng2 = skill[2]
    jineng3 = skill[3]
    jineng4 = skill[4]
    b = df.append([name, beidong, jineng1, jineng2, jineng3, jineng4])

    d = pd.DataFrame(df, columns=columns)
    # index=False表示输出不显示索引值
    d.to_excel("王者荣耀英雄与技能.xlsx", index=False)

这是链接里面的源代码,方便阅读。

一、网页源代码和elements的区别

1.例子

首先打开王者荣耀全部英雄所在的网址

英雄资料列表页-英雄介绍-王者荣耀官方网站-腾讯游戏

右键,可以看到查看网页源代码检查-审查元素选项。

查看网页源代码(下图为部分截图)

 检查---elements

查看网页源代码检查-审查元素的页面,看着好像相同,但是如果仔细数的话,你会发现查看网页源代码中缺少了云缨-曜的英雄相关信息。

2.原因

查看源代码:别人服务器发送到浏览器的原封不动的代码。

检查-审查元素:看到的就是最终的html代码。即:源代码 + 网页js渲染 。

所以查看网页源代码检查-审查元素中的内容不一定是一样的。

而用requests模块爬取到的response.text其实是网页源代码中的内容,未被网页js渲染。

所以此前代码是根据网页源代码爬取的,存在数据的缺失。

二、解决方案

1.寻找数据存储文件

我们需要去寻找数据存在于哪个文件中,

经查找,我们发现王者荣耀英雄存储在herolist.json文件中。

2.处理json文件

herolist.json的网址是https://pvp.qq.com/web201605/js/herolist.json

网页中显示的是乱码格式,通过下面代码可以正常显示json中的中文

import requests

url = 'https://pvp.qq.com/web201605/js/herolist.json'
headers = {
    'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'
}
response = requests.get(url, headers=headers)
print(response.text)

herolist = json.loads(response.text)

通过json.loads()将其他类型的对象转为python对象,方便后续的处理。

注意load和loads的区别,loads()操作的是字符串,而load()操作的是文件流。

https://pvp.qq.com/web201605/herodetail/538.shtml

https://pvp.qq.com/web201605/herodetail/155.shtml

 

 

可以发现json文件中的ename的数字就是构成具体英雄网页的数字,因此我们需要ename,

ename = []
for item in herolist:
    herolist_ename = item["ename"]
    ename.append(herolist_ename)

这段代码的作用是遍历herolist,将里面ename的值存储到ename列表中。

上面一行是herolist的内容,下面一行是ename列表的内容。

三、爬取相关数据

爬取到ename后,就可以遍历它,构造url进行爬取,爬取的步骤与之前一致。

python爬虫------王者荣耀英雄及技能爬取并保存信息到excel

base_url = "https://pvp.qq.com/web201605/herodetail/{}.shtml"
df = []
# 标题栏
columns = ['英雄', '被动', '技能1', '技能2', '技能3', '技能4']
a = 1
for i in ename:
    # print(i)
    true_url = base_url.format(i)
    r = requests.get(true_url, headers=headers)
    r.encoding = "gbk"
    names = re.compile('<label>(.*?)</label>')
    name = names.findall(r.text)[0]
    # 用来显示英雄个数
    print(str(a) + name)
    a += 1
    # 没有这个[0],会使得excel中的数据是['云中君'],即中文名外面还有引号和[]
    skills = re.compile('<p class="skill-desc">(.*?)</p>', re.S)
    skill = skills.findall(r.text)
    # 数据清洗
    beid = skill[0]
    beidong = beid.replace("被动:", "")
    jineng1 = skill[1]
    jineng2 = skill[2]
    jineng3 = skill[3]
    jineng4 = skill[4]
    b = df.append([name, beidong, jineng1, jineng2, jineng3, jineng4])
    d = pd.DataFrame(df, columns=columns)
    # index=False表示输出不显示索引值
    d.to_excel("王者荣耀英雄与技能.xlsx", index=False)
由于大部分英雄的被动文本中存在被动:,,而小部分没有这些内容,所以需要
beidong = beid.replace("被动:", "")这段代码进行数据整理。

 四、全部代码展示

import requests
import json
import re
import pandas as pd
url = 'https://pvp.qq.com/web201605/js/herolist.json'
headers = {
    'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'
}
response = requests.get(url, headers=headers)
# print(response.text)
herolist = json.loads(response.text)
# print(herolist)
ename = []
for item in herolist:
    herolist_ename = item["ename"]
    ename.append(herolist_ename)
# print(ename)

base_url = "https://pvp.qq.com/web201605/herodetail/{}.shtml"
df = []
# 标题栏
columns = ['英雄', '被动', '技能1', '技能2', '技能3', '技能4']
a = 1
for i in ename:
    # print(i)
    true_url = base_url.format(i)
    r = requests.get(true_url, headers=headers)
    r.encoding = "gbk"
    names = re.compile('<label>(.*?)</label>')
    name = names.findall(r.text)[0]
    # 用来显示英雄个数
    print(str(a) + name)
    a += 1
    # 没有这个[0],会使得excel中的数据是['云中君'],即中文名外面还有引号和[]
    skills = re.compile('<p class="skill-desc">(.*?)</p>', re.S)
    skill = skills.findall(r.text)
    # 数据清洗
    beid = skill[0]
    beidong = beid.replace("被动:", "")
    jineng1 = skill[1]
    jineng2 = skill[2]
    jineng3 = skill[3]
    jineng4 = skill[4]
    b = df.append([name, beidong, jineng1, jineng2, jineng3, jineng4])
    d = pd.DataFrame(df, columns=columns)
    # index=False表示输出不显示索引值
    d.to_excel("王者荣耀英雄与技能.xlsx", index=False)


五、结果展示

 

六、总结

对于数据藏在json文件中时,首先要找到相应的文件。接下来进行解析等一系列操作。

我试过lxml和bs4解析,结果发现步骤非常繁琐,lxml解析出来经常为[]。

因此还是老老实实用re吧

经过爬取我才发现王者荣耀有106个英雄,平时上号时我都不在意这些

标签:herolist,爬取,ename,url,为例,---,json,skill,源代码
来源: https://blog.csdn.net/knighthood2001/article/details/120449819