python爬虫入门之爬取英雄联盟官网的所有英雄数据

python爬虫入门之爬取英雄联盟官网的所有英雄数据

本文是Python学期实训时所写的爬虫项目,在这里分享给你,希望能对你有所帮助。 传送门—>安装Python环境及PyCharm编辑器并配置爬虫环境

文章目录

找到网页中有价值的内容及其所处在源码中的位置 编写爬虫代码,将信息爬取下来并保存到本地文件中。 将爬取到的数据进行分析。

内容部分:

一.找到网页中有价值的内容及其所处在源码中的位置

英雄联盟官方网址: 英雄联盟全新官方网站-腾讯游戏 英雄数据信息网址: 游戏资料-英雄联盟官方网站-腾讯游戏 本小节操作的目的是:找出官网上对自己有价值的信息及其所在网页源代码中的位置。

第一步:分析网页信息

所有的英雄页: 在英雄联盟—游戏资料中,展示了所有的英雄数据,包括有原皮肤,英雄名以及英雄信息信息的网址链接。通过按下 F12 键我们可以查看到网页的源代码,展示如下:

为了方便我们快速获取网页中某一部分的源码信息,我们可以点击屏幕中间位置最左边的箭头图标,去网页中找到该部分对应信息的源代码。( 在这里小编以安妮为例 )

在此我们可以分析得出,一个<li>标签下放置着一个英雄的部分信息,其中,英雄详细信息的地址链接放置在 a 标签的 href 属性中,英雄的姓名全称放置在 a 标签的 title 属性中,英雄原皮肤图片地址链接放置在 img 标签下的 src 属性中,英雄的简称姓名放置在 p 标签中。

当我们点击进入英雄详细信息的展示页面时,通过同样的方法我们可以得到以下内容:

单个英雄职业信息: 英雄的职业信息是放置在 id 为 “DATA tags” 的 div 容器下的 span 标签中。

单个英雄皮肤信息: 英雄的所有皮肤信息被放置在 id 为 “skinNAV” 的 ul 容器下的 li 标签中。在每一个 li 标签内的 a 标签内的 img 标签中的 alt 属性存放的是英雄皮肤的名字, src 属性存放的是英雄每个皮肤的图片网址,

单个英雄背景故事: 英雄的背景故事信息被放置在 id 为 “DATAlore” 的 div 容器中,但是内容并不完整。通过点击 id 为 “Gmore”的 a 标签,可以将英雄的背景故事信息完整的添加在 id 为 “DATAlore” 的 div 容器中展示出来。 单个英雄技能信息: 英雄技能信息被放置在 class 名为 “skilltitle” 的 div 容器下,h5 标签中放置的是英雄的技能名,em 标签中放置的是技能触发方式。通过点击 id 为 “DATAspellsNAV” 的 ul 标签下的每个 li 标签,可以将 class 名为 “skilltitle” 的 div 容器中的信息修改成别的技能介绍。 当你使用某一英雄时的使用技巧: 当你使用某一英雄时的使用技巧介绍被放在 id 为 “DATAallytips” 的 dl 标签下的 dd 标签下的所有 p 标签中。

当敌人使用某一英雄时的应对技巧: 当敌人使用某一英雄时的应对技巧介绍被放在 id 为 “DATAenemytips” 的 dl 标签下的 dd 标签下的所有 p 标签中。 综上所述,我们已经找到了对自己有用的信息,也找到了信息所在网页源码中的位置,接下来要做的就是使用爬虫代码,将信息爬取下来并保存到本地文件中。

二.编写爬虫代码,将信息爬取下来并保存到本地文件中。

```python

# 导入必要的库文件

# 导入selenium抓取动态网页信息

from selenium import webdriver

# 导入时间控制器

import time

# 导入正则表达式

import re

from urllib.request import urlretrieve

import os

from xlutils import copy

import xlrd

# 定义全局变量

# 所有的英雄全名及其详细信息的网址

allHeroParticularlyMessageUrl = []

heroNameList = []

heroJobList = []

heroSkinNumberList = []

heroPassiveSkillsList = []

heroQSkillsList = []

heroWSkillsList = []

heroESkillsList = []

heroRSkillsList = []

heroMessageList = []

# 主程序

def main():

# 定义一个计数器

count = 1

#定义存储的起始位置

start = 1

#定义结束位置

end = ""

#创建皮肤图片保存目录

imageFilePath = 'C:/Users/24010/Desktop/skinImages'

if not os.path.exists(imageFilePath):

os.mkdir(imageFilePath)

print("...开始爬取数据...")

# 定义初始爬取网页的URL

basciPageUrl = "https://lol.qq.com/data/info-heros.shtml"

print("...爬取所有的英雄全名及其详细信息的网址执行中...")

seleniumForGetAllHeroURL(basciPageUrl)

excel_path = './heroBasicInformationExcel.xls' # 文件路径

rbook = xlrd.open_workbook(excel_path, formatting_info=True) # 打开文件

book = copy.copy(rbook) # 复制文件并保留格式

sheet = book.get_sheet(0) # 索引sheet表

# 获取每个英雄的详细详细信息

for oneHeroUrl in allHeroParticularlyMessageUrl:

#保存中断后,可修改start的值,继续修改

if end == "":

if start <= count:

print("开始保存第" + str(count) + "个英雄的数据!")

saveDate("开始保存第" + str(count) + "个英雄的数据!", "a")

saveDate("", "a")

seleniumForGetHeroAllMessage(oneHeroUrl[1], count)

saveDateInExcel(count - 1, book, sheet)

else:

pass

else:

if start <= count <= end:

print("开始保存第" + str(count) + "个英雄的数据!")

saveDate("开始保存第" + str(count) + "个英雄的数据!", "a")

saveDate("", "a")

seleniumForGetHeroAllMessage(oneHeroUrl[1], count)

saveDateInExcel(count - 1, book, sheet)

else:

pass

count = count + 1

# 获取所有的英雄全名及其详细信息的网址

def seleniumForGetAllHeroURL(basciPageUrl):

# 打开浏览器

browser = webdriver.Chrome()

# 访问网页

browser.get(basciPageUrl)

time.sleep(20)

# 查找信息

getli = browser.find_element_by_id('jSearchHeroDiv').find_elements_by_tag_name('li')

for Everyone in getli:

EveryoneUrl = Everyone.find_element_by_tag_name('a').get_attribute('href')

EveryoneTitle = Everyone.find_element_by_tag_name('a').get_attribute('title')

allHeroParticularlyMessageUrl.append([EveryoneTitle, EveryoneUrl])

browser.close()

print("...爬取所有的英雄全名及其详细信息的网址并存储完成...")

# 获取该英雄的详细信息

def seleniumForGetHeroAllMessage(heroMessageUrl, count):

# 打开浏览器

browser = webdriver.Chrome()

while True:

# 访问网页

browser.get(heroMessageUrl)

time.sleep(5)

browser.execute_script('window.scrollTo(0, 0)')

time.sleep(2)

# 滑动页面

browser.execute_script('window.scrollBy(0, document.body.scrollHeight*0.2)')

time.sleep(1)

browser.execute_script('window.scrollBy(0, document.body.scrollHeight*0.2)')

time.sleep(1)

browser.execute_script('window.scrollBy(0, document.body.scrollHeight*0.2)')

time.sleep(1)

browser.execute_script('window.scrollBy(0, document.body.scrollHeight*0.2)')

time.sleep(1)

# 获取到查看更多按钮

button = browser.find_element_by_class_name('cgray')

# 点击上步按钮

button.click()

# <---time.sleep()必须写,网速不佳的话,适当延长时间--->

time.sleep(1)

if len(browser.find_element_by_id('skinNAV').find_elements_by_tag_name("li")) > 1:

break

else:

print("访问此页面时网络不佳-->" + heroMessageUrl)

time.sleep(10)

# 获取基本信息

findMostmessage(browser, heroMessageUrl)

# 获取完基本信息后再将页面到滚动条的五分之三处

browser.execute_script('window.scrollTo(0, document.body.scrollHeight*0.6)')

# <---time.sleep()必须写,网速不佳的话,适当延长时间--->

time.sleep(1)

# 获取英雄技能

findHeroAllSkills(browser, count)

# ...查找...

def findMostmessage(browser, heroMessageUrl):

# ----------------------------------------查找信息---------------------------------------------

# 英雄名

thisHeroName = browser.find_element_by_id('DATAname').text + browser.find_element_by_id('DATAtitle').text

# 英雄职业

thisHeroJob = browser.find_element_by_id('DATAtags').find_element_by_tag_name('span').text

# 英雄背景故事

thisHeroStory = browser.find_element_by_id('DATAlore').text

# 自己使用该英雄时的技巧

tipsForUsToUseThisHero = ""

# 敌人使用该英雄时的技巧

tipsForEnemyUseThisHero = ""

# 皮肤名称及其图片链接

heroSkinImgs = []

# -----------------------------------------查找信息---------------------------------------------

# 技巧对应的英雄名

whileYouUseWhichHero = browser.find_element_by_id('DATAallytips').find_element_by_tag_name('dt').text

whileEnemyUseWhichHero = browser.find_element_by_id('DATAenemytips').find_element_by_tag_name('dt').text

# 自己使用时的技巧合集

tipListForUsToUseThisHero = browser.find_element_by_id('DATAallytips').find_element_by_tag_name(

'dd').find_elements_by_tag_name('p')

# 别人使用时的技巧合集

tipListForEnemyUseThisHero = browser.find_element_by_id('DATAenemytips').find_element_by_tag_name(

'dd').find_elements_by_tag_name('p')

# 自己使用时的技巧字符串

for tip in tipListForUsToUseThisHero:

tipsForUsToUseThisHero = tipsForUsToUseThisHero + tip.text[1:len(tip.text)]

tipsForUsToUseThisHero = "4," + whileYouUseWhichHero + " : " + tipsForUsToUseThisHero

# 敌人使用时的技巧字符串

for tip in tipListForEnemyUseThisHero:

tipsForEnemyUseThisHero = tipsForEnemyUseThisHero + tip.text[1:len(tip.text)]

tipsForEnemyUseThisHero = "5," + whileEnemyUseWhichHero + " : " + tipsForEnemyUseThisHero

# -------------------------------------查找图片-------------------------------------------

heroSkinImg = browser.find_element_by_id('skinNAV').find_elements_by_tag_name('li')

heroSkillImgsLi = browser.find_element_by_id('DATAspellsNAV').find_elements_by_tag_name('li')

findHeroSkillSrcNumber = re.compile(r'act/img/skin/small(.*?).jpg')

#创建目录

path1 = "C:/Users/24010/Desktop/skinImages/" + thisHeroName

if not os.path.exists(path1):

os.mkdir(path1)

#循环该英雄皮肤url

for img in heroSkinImg:

heroSkinName = img.find_element_by_tag_name('a').get_attribute('title')

smalllImgsrc = img.find_element_by_tag_name('img').get_attribute('src')

HeroSkillSrcNumber = re.findall(findHeroSkillSrcNumber, str(smalllImgsrc))[0]

#重新拼接图片url

heroSkinImgUrl = "https://game.gtimg.cn/images/lol/act/img/skin/big" + HeroSkillSrcNumber + ".jpg"

#拼接图片保存地址

if heroSkinImgUrl != "https://game.gtimg.cn/images/lol/act/img/skin/big235010.jpg":

path2 = path1 + "/image" + HeroSkillSrcNumber + ".jpg"

#保存图片为本地文件

urlretrieve(heroSkinImgUrl, path2)

heroSkinImgs.append([heroSkinName, heroSkinImgUrl])

# 创建目录

skillpath1 = "C:/Users/24010/Desktop/skinImages/" + thisHeroName + "/技能图片"

if not os.path.exists(skillpath1):

os.mkdir(skillpath1)

jineng = ["被动技能", "Q技能", "W技能", "E技能", "R技能"]

i = 0

# 循环该英雄技能url

for img in heroSkillImgsLi:

heroSkillImgUrl = img.find_element_by_tag_name("img").get_attribute('src')

# 拼接图片保存地址

skillpath = skillpath1 + "/" + jineng[i] + ".png"

# 保存图片为本地文件

urlretrieve(heroSkillImgUrl, skillpath)

i = i + 1

# ----------------------------保存数据---------------------

saveDate(thisHeroName + " 详细信息网址 " + heroMessageUrl, "a")

heroMessageList.append(heroMessageUrl)

saveDate("", "a")

saveDate("1,英雄名:" + thisHeroName, "a")

heroNameList.append(thisHeroName)

saveDate("", "a")

saveDate("2,英雄职业:" + thisHeroJob, "a")

heroJobList.append(thisHeroJob)

saveDate("", "a")

saveDate("3,英雄背景故事:" + thisHeroStory, "a")

saveDate("", "a")

saveDate(tipsForUsToUseThisHero, "a")

saveDate("", "a")

saveDate(tipsForEnemyUseThisHero, "a")

saveDate("", "a")

#图片个数

imgcount = 0

for img in heroSkinImgs:

imgcount = imgcount + 1

date = "6." + str(imgcount) + img[0] + " : " + img[1]

#保存皮肤名和图片链接到txt文件里面

saveDate(date, "a")

heroSkinNumberList.append(imgcount)

saveDate("", "a")

# ...查找英雄技能及其介绍

def findHeroAllSkills(browser, count):

# 获取技能点击列表

button = browser.find_element_by_id('DATAspellsNAV').find_elements_by_tag_name('li')

# 逐个点击技能按钮

#定义计数器

skillcount = 7

for i in range(0, 5):

# 点击第i个按钮

button[i].click()

# <---time.sleep()必须写,网速不佳的话,适当延长时间--->

time.sleep(1)

skillName = browser.find_element_by_class_name('skilltitle').find_element_by_tag_name('h5').text

saveDate(str(skillcount) + ".1,技能名称:" + skillName, "a")

skillTriggerMode = browser.find_element_by_class_name('skilltitle').find_element_by_tag_name('em').text

saveDate(str(skillcount) + ".2,技能触发方式:" + skillTriggerMode, "a")

skillInformation = browser.find_element_by_id('DATAspells').find_element_by_tag_name('p').text

saveDate(str(skillcount) + ".3,技能内容介绍:" + skillInformation, "a")

saveDate("", "a")

skillcount = skillcount + 1

#存技能名

if i == 0:

heroPassiveSkillsList.append(skillName)

if i == 1:

heroQSkillsList.append(skillName)

if i == 2:

heroWSkillsList.append(skillName)

if i == 3:

heroESkillsList.append(skillName)

if i == 4:

heroRSkillsList.append(skillName)

saveDate("", "a")

saveDate("", "a")

# 关闭浏览器

browser.close()

print("第" + str(count) + "条英雄数据保存成功!")

# ------------------------------保存数据---------------------------------

def saveDate(date, mode):

filename = 'allHeroMessages.txt'

with open(filename, mode, encoding='utf-8') as f:

f.write(date + "\n")

#------------------------------保存到Excel-----------------------------

def saveDateInExcel(j, book, sheet):

col = ["英雄名称", "英雄职业", "英雄皮肤数量", "被动技能名称", "Q技能名称", "W技能名称", "E技能名称", "R技能名称", "英雄信息链接"]

if j == 0:

for i in range(0, 9):

sheet.write(0, i, col[i])

sheet.write(j+1, 0, heroNameList[0])

sheet.write(j + 1, 1, heroJobList[0])

sheet.write(j + 1, 2, heroSkinNumberList[0])

sheet.write(j + 1, 3, heroPassiveSkillsList[0])

sheet.write(j + 1, 4, heroQSkillsList[0])

sheet.write(j + 1, 5, heroWSkillsList[0])

sheet.write(j + 1, 6, heroESkillsList[0])

sheet.write(j + 1, 7, heroRSkillsList[0])

sheet.write(j + 1, 8, heroMessageList[0])

heroNameList.clear()

heroJobList.clear()

heroSkinNumberList.clear()

heroPassiveSkillsList.clear()

heroQSkillsList.clear()

heroWSkillsList.clear()

heroESkillsList.clear()

heroRSkillsList.clear()

heroMessageList.clear()

book.save('./heroBasicInformationExcel.xls') # 保存文件

# 调用主程序,开始执行本程序

if __name__ == "__main__":

main()

print("...执行完成...")

《解释部分等我有时间再更新,如果你直接copy我的代码到你编辑器,大概率你是运行不出来的(需要配置浏览器插件),奸笑中~~》

三.将爬取到的数据进行分析。

饼图(英雄联盟各职业英雄数量分布图)

import matplotlib.pyplot as plt

# 饼图

data = {

'坦克': (19, 'red'),

'战士': (42, 'yellow'),

'法师': (34, 'blue'),

'辅助': (15, 'green'),

'射手': (25, 'orange'),

'刺客': (17, 'gray'),

}

# 设置绘图对象的大小

fig = plt.figure(figsize=(8, 8))

heros = data.keys()

values = [x[0] for x in data.values()]

colors = [x[1] for x in data.values()]

ax1 = fig.add_subplot(111)

ax1.set_title('英雄联盟各职业英雄数量分布图')

labels = ['{}:{}'.format(skin, value) for skin, value in zip(heros, values)]

explode = [] # 设置饼图的凸出显示

ax1.pie(values, labels=labels, colors=colors, shadow=True) # 画饼状图, 并且指定标签和对应的颜色 指定阴影效果

# plt.savefig('pie.jpg') # 保存成图片

plt.rcParams['font.sans-serif']=['SimHei'] # 中文

plt.show()

结果:

柱状图(英雄皮肤数量分布图)

# encoding: utf-8

import matplotlib.pyplot as plt

index = ['1-3', '4-6', '7-9', '10-12', '13-15', '16-18']

values = [12, 31, 42, 49, 17, 1]

plt.bar(index, values)

plt.xlabel("英雄数量")

plt.ylabel("皮肤数量")

plt.rcParams['font.sans-serif']=['SimHei']

plt.show()

结果

尾语

如果觉得本文写的还不错的话,求赞、求收藏、求关注、求转发、最重要的是给小博主点个大大的订阅,你的鼓励就是我前进的最大动力,我们下期再见。

相关推荐

圣母在哪里 耶稣也在哪里
365bet在线官网

圣母在哪里 耶稣也在哪里

08-14 👁️ 7637
微信怎么清粉
best365官网登陆

微信怎么清粉

07-02 👁️ 9002
常用成语
bet28365365体育投注

常用成语

07-02 👁️ 4096