Python:使用爬虫获取存储在 Excel 中的世界大学学术排名并进行可视化输出
文章目录
- 问题描述
- 问题分析
- 结果展示
- 代码实现
- 解法一:BeautifulSoup 解析 HTML
- 解法二:XPath 解析 HTML
- 解法一:BeautifulSoup 解析 HTML
- 解法二:XPath 解析 HTML
问题描述
从 http://www.zuihaodaxue.cn/ 网站中爬取数据,获取世界大学学术排名(Top10)
- 爬取的数据保存为Excel文件(.xlsx)
- 进一步考虑,数据可视化输出(附加)
- 采用
xpath
或者BeautifulSoup
语法提取数据;
问题分析
换汤不换药,相关解释请查阅这篇文章:Python:使用爬虫获取中国最好的大学排名数据(爬虫入门)
不过之前那篇文章介绍的是使用 BeautifulSoup
解析的 HTML
页面,这次我们再使用 XPath
来解析。
这里就不在赘述了,直接写代码。
结果展示
不过我觉得转化为饼图会更直观一些,但是那样会有子图,如果有时间我会更新一下饼图看看效果会不会更好一点。
代码实现
准备工作,请确保安装了以下库函数。
需要安装 pyecharts
(与 matplotlib
相比更美观,具有交互性,适合网站页面或商业报告展示)。
安装适用命令:
pip install -i http://pypi.tuna.tsinghua.edu.cn/simple/ --trusted-host pypi.tuna.tsinghua.edu.cn pyecharts
关于如何使用请查阅 官方文档。
目标网站:http://www.zuihaodaxue.cn/ARWU2019.html
解法一:BeautifulSoup 解析 HTML
"""
@author: shoo Wang
@contact: wangsuoo@foxmail.com
@file: demo03.py
@time: 2020/5/10 0010
"""
import requests as rq
from bs4 import BeautifulSoup as Bs
import pandas as pd
import numpy as np
from pyecharts.charts import Bar
from pyecharts import options as opts
from pyecharts.globals import ThemeType
# 获取数据,就是通过访问网页,把他的html源代码拿过来
def getData(resLoc):
rp = rq.get(resLoc)
rp.encoding = 'utf-8'
return rp.text
# 最关键的部分: 数据处理,我们的目标是将文本格式的 html 网页转化为表格的形式;
def dataProcessing(html, num):
bs = Bs(html, features='lxml')
# 获取 html 中 DOM 树的表格结构
table = bs.table.tbody.find_all('tr', limit=num, recursive=True)
universityList = []
# 遍历该表格,筛选出我们需要的信息存储到 universityList 中
for tr in table:
tds = tr.find_all('td')
contents = [td.contents for td in tds]
contents[1] = contents[1][0].contents
# 这里网页中是图片,但是可以通过截取字符串获取到国家的英文简写
contents[2] = contents[2][0]['href'].split('/')[1].split('.')[0]
contents = [''.join(i) for i in contents]
# ['1', '哈佛大学', 'USA', '1', '100.0', '100.0', '100.0', '100.0', '100.0', '100.0', '78.2']
universityList.append(contents)
# 自己写表头,因为网站上爬太复杂了
thf = ['世界排名', '学校', '国家', '在该国家的排名', '总分', '校友获奖', '教师获奖',
'高被引学者', 'N&S论文', '国际论文', '师均表现']
# 转化为 DataFrame 结构,因为这种结构很好转化为 Excel
pd_universityList = pd.DataFrame(np.array(universityList), columns=thf)
return pd_universityList
# 负责保存数据到本地磁盘
def saveData(data):
data.to_excel('university.xlsx', index=False)
# 数据可视化
def can_view(universityList):
# 将 pandas 数据类型转化为 numpy 数组
data = np.array(universityList)
# 将 data 转化为列表,只要第4个数据项到第10个数据项,且这些数据都为数字
ans = [[eval(i[da]) for i in data] for da in range(4, 11)]
# 获取大学名称作为横坐标
un = [i[1] for i in data]
# 在 InitOpts 中可以设置主题样式和图表的宽度
bar = (Bar(init_opts=opts.InitOpts(theme=ThemeType.LIGHT, width='2000px', height='700px'))
.add_xaxis(un)
.add_yaxis('总分', da1)
.add_yaxis('校友获奖', da2)
.add_yaxis('教师获奖', da3)
.add_yaxis('高被引学者', da4)
.add_yaxis('N&S论文', da5)
.add_yaxis('国际论文', da6)
.add_yaxis('师均表现', da7)
# 设置标题, AxisOpts 是设置横坐标的每一个数据项的倾斜程度
.set_global_opts(title_opts=opts.TitleOpts(title="世界大学学术排名"),
xaxis_opts=opts.AxisOpts(name_rotate=60, name="大学名称", axislabel_opts={"rotate": 25}))
)
bar.render()
def main(num):
# 由于该网站最多有 1000 个大学,所以输入的数字不能大于 1000 ,否则什么也不做
if num >= 1000:
print("数量不能大于1000")
return
else:
url = 'http://www.zuihaodaxue.cn/ARWU2019.html'
universityList = dataProcessing(getData(url), num)
saveData(universityList)
print("文件保存成功!")
can_view(universityList)
# 测试,爬取前10名大学的信息
main(10)
由于我对于 numpy
库不是很熟,所以可能有些地方对数据的处理多此一举了,还请读者指出问题所在。
运行的结果是一个 html
文件,可以直接在浏览器运行,他是使用 js
加载的。
在该函数中可以指定文件名,如果不指定则默认为 render.html
。
解法二:XPath 解析 HTML
该方法与方法一的区别仅仅在于解析 HTML
时的方法不同,常用的方法有三种:
- BeautifulSoup
- XPath
- Regular Expression
以上任意一种方法都可以实现,看个人喜好。这里也提供第二种方法来实现上述内容。
本项目依赖于 lxml
库。
我们只修改dataProcessing
的函数内容即可:
下面思路分析一下,一步一步的解决问题:
首先要获取这个 element
树:
html = etree.HTML(html)
然后我们先获取大学名称,在网页中打开控制台调试:
输入 XPath
语法: //tbody/tr/td/a/text()
,不会语法的可以先谷歌一下 XPath
语法:
我们以前十名大学为例,结果为:
['哈佛大学', '斯坦福大学', '剑桥大学', '麻省理工学院', '加州大学-伯克利', '普林斯顿大学', '牛津大学', '哥伦比亚大学', '加州理工学院', '芝加哥大学']
下面我们来获取图片信息:
虽然我们无法获取图片数据,但是可以通过截取字符串来获取国家的简写:
img_xpath = html.xpath('//tbody/tr//a/img/@src')[:num]
img = [i.split('/')[2].split('.')[0] for i in img_xpath]
结果为:
['USA', 'USA', 'UK', 'USA', 'USA', 'USA', 'UK', 'USA', 'USA', 'USA']
然后就是最简单的其余数据项的获取了:
nums = [[eval(j) for j in html.xpath('//tbody/tr[' + str(i + 1) + ']/td/text()')[:num]] for i in range(num)]
这行代码执行完毕之后是这样的:
[
['1', '1', '100.0', '100.0', '100.0', '100.0', '100.0', '100.0', '78.2'],
['2', '2', '75.1', '45.2', '88.5', '73.3', '79.2', '76.6', '53.8'], ... ]
就是每一行数据除去 国家名称 和 国家简称。鉴于该写法可读性较低,所以这里稍微解释一下:
- 这里使用了两个列表推导式;
- 里面的小列表的任务时通过
XPath
获取数据之后对于每一个数字要转化为数字类型; - 外面的大列表负责控制小列表的个数,同时保存到 nums 中。
所以下面我们要做的就是将我们之前获取的这两个数据添加到这个列表中,一个循环即可,这里使用 idx
作为下标的标记。
# 下面把 univ 和 img 加到 nums 列表中
idx = 0
for num in nums:
num.insert(1, univ[idx])
num.insert(2, img[idx])
idx += 1
后面的就和其他的一样了。
来看一下整体的代码:
"""
@author: shoo Wang
@contact: wangsuoo@foxmail.com
@file: demo09.py
@time: 2020/5/11 0011
"""
import requests as rq
from lxml import etree
import pandas as pd
import numpy as np
from pyecharts.charts import Bar
from pyecharts import options as opts
from pyecharts.globals import ThemeType
# 获取数据,就是通过访问网页,把他的html源代码拿过来
def getData(resLoc):
rp = rq.get(resLoc)
rp.encoding = 'utf-8'
return rp.text
# 最关键的部分: 数据处理,我们的目标是将文本格式的 html 网页转化为表格的形式;
def dataProcessing(html, num):
html = etree.HTML(html)
univ = html.xpath('//tbody/tr/td/a/text()')[:num] # 大学名称
nums = [[eval(j) for j in html.xpath('//tbody/tr[' + str(i + 1) + ']/td/text()')[:num]] for i in range(num)] # 数据项
img_xpath = html.xpath('//tbody/tr//a/img/@src')[:num]
img = [i.split('/')[2].split('.')[0] for i in img_xpath] # 大学国家的简称
# 合并列表
idx = 0
for num in nums:
num.insert(1, univ[idx])
num.insert(2, img[idx])
idx += 1
# 自己写表头,因为网站上爬太复杂了
thf = ['世界排名', '学校', '国家', '在该国家的排名', '总分', '校友获奖', '教师获奖',
'高被引学者', 'N&S论文', '国际论文', '师均表现']
# 转化为 DataFrame 结构,因为这种结构很好转化为 Excel
pd_universityList = pd.DataFrame(np.array(nums), columns=thf)
return pd_universityList
# 负责保存数据到本地磁盘
def saveData(data):
data.to_excel('university.xlsx', index=False)
# 数据可视化
def can_view(universityList):
# 将 pandas 数据类型转化为 numpy 数组
data = np.array(universityList)
# 将 data 转化为列表
ans = [[eval(i[da]) for i in data] for da in range(4, 11)]
# 获取大学名称作为横坐标
un = [i[1] for i in data]
# 在 InitOpts 中可以设置主题样式和图表的宽度
bar = (Bar(init_opts=opts.InitOpts(theme=ThemeType.LIGHT, width='2000px', height='700px'))
.add_xaxis(un)
.add_yaxis('总分', ans[0])
.add_yaxis('校友获奖', ans[1])
.add_yaxis('教师获奖', ans[2])
.add_yaxis('高被引学者', ans[3])
.add_yaxis('N&S论文', ans[4])
.add_yaxis('国际论文', ans[5])
.add_yaxis('师均表现', ans[6])
# 设置标题, AxisOpts 是设置横坐标的每一个数据项的倾斜程度
.set_global_opts(title_opts=opts.TitleOpts(title="世界大学学术排名"),
xaxis_opts=opts.AxisOpts(name_rotate=60, name="大学名称", axislabel_opts={"rotate": 25}))
)
bar.render()
def main(num):
# 由于该网站最多有 1000 个大学,所以输入的数字不能大于 1000 ,否则什么也不做
if num >= 1000:
print("数量不能大于1000")
return
else:
url = 'http://www.zuihaodaxue.cn/ARWU2019.html'
universityList = dataProcessing(getData(url), num)
saveData(universityList)
print("文件保存成功!")
can_view(universityList)
# 测试,爬取前10名大学的信息
main(10)
推荐阅读
-
包婷婷 (201550484)作业一 统计软件简介与数据操作-SPSS(Statistical Product and Service Solutions),"统计产品与服务解决方案"软件。最初软件全称为"(SolutionsStatistical Package for the Social Sciences),但是随着SPSS产品服务领域的扩大和服务深度的增加,SPSS公司已于2000年正式将英文全称更改为"统计产品与服务解决方案",标志着SPSS的战略方向正在做出重大调整。为IBM公司推出的一系列用于统计学分析运算、数据挖掘、预测分析和决策支持任务的软件产品及相关服务的总称SPSS,有Windows和Mac OS X等版本。 1984年SPSS总部首先推出了世界上第一个统计分析软件微机版本SPSS/PC+,开创了SPSS微机系列产品的开发方向,极大地扩充了它的应用范围,并使其能很快地应用于自然科学、技术科学、社会科学的各个领域。世界上许多有影响的报刊杂志纷纷就SPSS的自动统计绘图、数据的深入分析、使用方便、功能齐全等方面给予了高度的评价。 R统计软件介绍 R是一套完整的数据处理、计算和制图软件系统。其功能包括:数据存储和处理系统;数组运算工具(其向量、矩阵运算方面功能尤其强大);完整连贯的统计分析工具;优秀的统计制图功能;简便而强大的编程语言:可操纵数据的输入和输出,可实现分支、循环,用户可自定义功能。 与其说R是一种统计软件,还不如说R是一种数学计算的环境,因为R并不是仅仅提供若干统计程序、使用者只需指定数据库和若干参数便可进行一个统计分析。R的思想是:它可以提供一些集成的统计工具,但更大量的是它提供各种数学计算、统计计算的函数,从而使使用者能灵活机动的进行数据分析,甚至创造出符合需要的新的统计计算方法。 该语言的语法表面上类似 C,但在语义上是函数设计语言(functional programming language)的变种并且和Lisp 以及 APL有很强的兼容性。特别的是,它允许在"语言上计算"(computing on the language)。这使得它可以把表达式作为函数的输入参数,而这种做法对统计模拟和绘图非常有用。 R是一个免费的*软件,它有UNIX、LINUX、MacOS和WINDOWS版本,都是可以免费下载和使用的。在R主页那儿可以下载到R的安装程序、各种外挂程序和文档。在R的安装程序中只包含了8个基础模块,其他外在模块可以通过CRAN获得。 二、R语言 R是用于统计分析、绘图的语言和操作环境。R是属于GNU系统的一个*、免费、源代码开放的软件,它是一个用于统计计算和统计制图的优秀工具。 R作为一种统计分析软件,是集统计分析与图形显示于一体的。它可以运行于UNIX,Windows和Macintosh的操作系统上,而且嵌入了一个非常方便实用的帮助系统,相比于其他统计分析软件,R还有以下特点: 1.R是*软件。这意味着它是完全免费,开放源代码的。可以在它的网站及其镜像中下载任何有关的安装程序、源代码、程序包及其源代码、文档资料。标准的安装文件身自身就带有许多模块和内嵌统计函数,安装好后可以直接实现许多常用的统计功能。[2] 2.R是一种可编程的语言。作为一个开放的统计编程环境,语法通俗易懂,很容易学会和掌握语言的语法。而且学会之后,我们可以编制自己的函数来扩展现有的语言。这也就是为什么它的更新速度比一般统计软件,如,SPSS,SAS等快得多。大多数最新的统计方法和技术都可以在R中直接得到。[2] 3. 所有R的函数和数据集是保存在程序包里面的。只有当一个包被载入时,它的内容才可以被访问。一些常用、基本的程序包已经被收入了标准安装文件中,随着新的统计分析方法的出现,标准安装文件中所包含的程序包也随着版本的更新而不断变化。在另外版安装文件中,已经包含的程序包有:base一R的基础模块、mle一极大似然估计模块、ts一时间序列分析模块、mva一多元统计分析模块、survival一生存分析模块等等.[2] 4.R具有很强的互动性。除了图形输出是在另外的窗口处,它的输入输出窗口都是在同一个窗口进行的,输入语法中如果出现错误会马上在窗口口中得到提示,对以前输入过的命令有记忆功能,可以随时再现、编辑修改以满足用户的需要。输出的图形可以直接保存为JPG,BMP,PNG等图片格式,还可以直接保存为PDF文件。另外,和其他编程语言和数据库之间有很好的接口。[2] 5.如果加入R的帮助邮件列表一,每天都可能会收到几十份关于R的邮件资讯。可以和全球一流的统计计算方面的专家讨论各种问题,可以说是全世界最大、最前沿的统计学家思维的聚集地.[2] R是基于S语言的一个GNU项目,所以也可以当作S语言的一种实现,通常用S语言编写的代码都可以不作修改的在R环境下运行。 R的语法是来自Scheme。R的使用与S-PLUS有很多类似之处,这两种语言有一定的兼容性。S-PLUS的使用手册,只要稍加修改就可作为R的使用手册。所以有人说:R,是S-PLUS的一个“克隆”。 但是请不要忘了:R是免费的(R is free)。R语言源代码托管在github,具体地址可以看参考资料。[3] 。 R语言的下载可以通过CRAN的镜像来查找。 R语言有域名为.cn的下载地址,有六个,其中两个由Datagurn,由 中国科学技术大学提供的。R语言Windows版,其中由两个下载地点是Datagurn和 USTC提供的。 三、stata Stata 是一套提供其使用者数据分析、数据管理以及绘制专业图表的完整及整合性统计软件。它提供许许多多功能,包含线性混合模型、均衡重复反复及多项式普罗比模式。用Stata绘制的统计图形相当精美。 新版本的STATA采用最具亲和力的窗口接口,使用者自行建立程序时,软件能提供具有直接命令式的语法。Stata提供完整的使用手册,包含统计样本建立、解释、模型与语法、文献等超过一万余页的出版品。 除此之外,Stata软件可以透过网络实时更新每天的最新功能,更可以得知世界各地的使用者对于STATA公司提出的问题与解决之道。使用者也可以透过Stata. Journal获得许许多多的相关讯息以及书籍介绍等。另外一个获取庞大资源的管道就是Statalist,它是一个独立的listserver,每月交替提供使用者超过1000个讯息以及50个程序。 四、PYTHON
-
Python:使用爬虫获取存储在 Excel 中的世界大学学术排名并进行可视化输出