ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

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

2021-09-24 12:30:07  阅读:235  来源: 互联网

标签:herolist 爬取 ename url 为例 --- json skill 源代码


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

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

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有