2017-2020年世界各国GDP数据爬取
一 |
二 |
三 |
四 |
五 |
总分 |
|
|
|
|
|
|
一、选题的背景
通过爬取2017-2020年世界各国历年来的GDP数据,对爬取得到的数据进行数据清洗提取得到可以利用的数据,并绘制图表进行分析疫情前后的GDP走势,以及各大洲的GDP占比情况等,进一步探究世界各国、各大洲的发展情况,和研究疫情对各个国家、洲的影响程度。
二、设计方案
1.主题式网络爬虫名称:
2017-2020年世界各国GDP数据爬取
2.主题式网络爬虫爬取的内容与数据特征分析
爬取世界各国GDP网站得到国家、洲、GDP、世界占比、年份等数据,然后存储到csv文件中。
3.主题式网络爬虫设计方案概述
实现思路:先确定主题,数据的爬取,使用的是python里面的requests库,这个库可以对网站发起请求获取到对应的数据,再利用lxml库使用xpath技术解析出我们要的数据,再利用Matplotlib等库进行绘制可视化图,然后存储到本地。
技术难点:Html页面的解析及爬取过程中的文件保存。
三、主题页面的结构特征分析
1.主题页面的结构与特征分析
顺序结构:先通过requests爬取2017年-2020年世界全国GDP值,再用csv保存数据,最后读取数据进行可视化。
数据来源:https://www.kylc.com/stats/global/yearly/g_gdp/2020.html
该页面由div,td,tr等组成的世界各国GDP网html页面程序代码。
2.Htmls页面解析
所需页面代码:
3.节点(标签)查找方法与遍历方法
查找方式:find
遍历方式:for循环
四、实现步骤及代码
1.数据爬取与采集
import requests
from lxml import etree
import pandas as pd
import matplotlib.pyplot as plt
import warnings
#忽略警告
warnings.filterwarnings("ignore")
#显示中文
plt.rcParams['font.sans-serif'] = ['SimHei']
#浏览器的UA
headers = {'User-Agent':'Mozilla/4.0 (compatible; MSIE 7.0; AOL 9.5; AOLBuild 4337.35; Windows NT 5.1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)'}
def get_data(url):
for n in range(20):
try:
dfs=requests.get(url,headers=headers,timeout= 5,verify=False).text
except Exception:
pass
else:
break
return dfs
#新建表格存储数据
datas = pd.DataFrame()
#循环爬取每一年的数据
for year in range(2017,2021):
print(year)
#构造链接
url1 = 'https://www.kylc.com/stats/global/yearly/g_gdp/'+str(year)+'.html'
#获取网页源码
df1 = get_data(url1)
#转化为HTML格式数据
html1 = etree.HTML(df1)
#提取对应数据
df1 = html1.xpath('//tbody/tr/td[2]/text()')
df2 = html1.xpath('//tbody/tr/td[3]/text()')
df3 = html1.xpath('//tbody/tr/td[4]/text()')
df4 = html1.xpath('//tbody/tr/td[5]/text()')
#找到不要的数据标签
index1 = df1.index('全世界')
#删除数据
del df1[index1]
del df3[index1]
del df4[index1]
index2 = df1.index('欧盟地区')
del df1[index2]
del df3[index2]
del df4[index2]
print(df1)
print(df2)
print(df3)
print(df4)
#存入dataframe表格
data = pd.DataFrame()
data['国家'] = df1
data['洲'] = df2
data['GDP'] = df3
data['占世界%'] = df4
data['year'] = year
#合并到大表格
datas = pd.concat([datas,data])
datas.to_csv('D:/数据.csv')
df=pd.read_csv('D:/数据.csv')
df
爬取运行生成一个csv文件:
2.对数据进行清洗和处理
#清洗数据
datas['gdp']=datas['GDP'].map(lambda x:float(x.split('(')[-1].split(')')[0].replace(',','')))
#去掉占比的百分号
datas['占比'] = datas['占世界%'].map(lambda x:float(x.replace('%','')))
#去掉不要的列
datas.drop(['GDP','占世界%'],axis = 1,inplace = True)
#存入csv中
datas.to_csv('D:/清洗后数据.csv')
d=pd.read_csv('D:/清洗后数据.csv')
d
清洗后得到的csv文件:
3.数据分析与可视化
df = datas.groupby('year')[['gdp']].sum().reset_index()
df
#绘制折线图x轴和y轴,透明度为0.8,线条宽度为3
plt.plot(df['year'],df['gdp'],alpha=0.8,linewidth = 3)
#添加x轴标签、y轴标签和标签
plt.xlabel("year",fontsize=14)
plt.ylabel('gdp',fontsize=14)
plt.title('每年全球GDP变化')
# 生成网格
plt.grid()
#显示图像
plt.show()
#绘制水平柱状图
plt.barh(d['year'],d['gdp'],label='2017年-2020年世界全国GDP值')
#显示图像
plt.show()
#看看历年gdp均值排名前10的国家
df1 = datas.groupby('国家')[['gdp']].mean().reset_index().sort_values(by = 'gdp',ascending = False).iloc[:10]
df1
#绘制柱状图
#创建figure对象,宽10英寸,高6英寸
plt.figure(figsize = (10,6))
#绘制柱状图,透明度为0.8
plt.bar(df1['国家'],df1['gdp'],alpha=0.8)
#添加x轴标签、y轴标签和标题标签
plt.xlabel("国家",fontsize=14)
plt.ylabel('gdp',fontsize=14)
plt.title('GDP均值国家排名TOP10')
# 生成网格
plt.grid()
#x轴标签旋转90度
plt.xticks(rotation=90)
#显示图像
plt.show()
#绘制散点图
plt.scatter(df1['国家'],df1['gdp'],color='k',s=25,marker="o")
#显示图像
plt.show()
#绘制直方图
import seaborn as sns
sns.distplot(df1['gdp'])
fig,axes=plt.subplots(2,2)
#默认绘图效果
sns.distplot(df1['gdp'],ax=axes[0][0])
#kde=False:不显示密度曲线
sns.distplot(df1['gdp'],kde=False,ax=axes[0][1])
#rug=True:在坐标轴上添加地毯图
sns.distplot(df1['gdp'],rug=True,ax=axes[1][0])
#调节vertical\hist_kws和kde_kws参数,改变直方图方向、坐标轴和密度曲线颜色
sns.distplot(df1['gdp'],vertical=True,hist_kws={'color':'blue','label':'hist'},kde_kws = {'color':'red','label':'KDE'},ax=axes[1][1])
#显示图像
plt.show()
#五大洲历年GDP总和
df2 = datas.groupby('洲')[['gdp']].sum().reset_index()
df2['占比'] = df2['gdp']/df2['gdp'].sum()
df2
#绘制小提琴
sns.violinplot(df2['gdp'])
#显示图像
plt.show()
#绘制扇形图
#准备数据
values = list(df2['占比'])
#准备标签
labels = list(df2['洲'])
#使用自定义颜色
colors = ['red','pink','magenta','purple','orange']
#将横、纵坐标轴标准化处理,保证饼图是一个正圆,否则为椭圆
plt.axes(aspect='equal')
#控制X轴和Y轴的范围(用于控制饼图的圆心、半径)
plt.xlim(0,8)
plt.ylim(0,8)
#不显示边框
plt.gca().spines['right'].set_color('none')
plt.gca().spines['top'].set_color('none')
plt.gca().spines['left'].set_color('none')
plt.gca().spines['bottom'].set_color('none')
#绘制饼图
plt.pie(x=values, #绘制数据
labels=labels,#添加编程语言标签
colors=colors, #设置自定义填充色
autopct='%.1f%%',#设置百分比的格式,保留3位小数
pctdistance=0.5, #设置百分比标签和圆心的距离
labeldistance=1.2,#设置标签和圆心的距离
startangle=180,#设置饼图的初始角度
center=(4,4),#设置饼图的圆心(相当于X轴和Y轴的范围)
radius=3.8,#设置饼图的半径(相当于X轴和Y轴的范围)
counterclock= False,#是否为逆时针方向,False表示顺时针方向
wedgeprops= {'linewidth':1,'edgecolor':'green'},#设置饼图内外边界的属性值
textprops= {'fontsize':12,'color':'black'},#设置文本标签的属性值
frame=1)#是否显示饼图的圆圈,1为显示
#不显示X轴、Y轴的刻度值
plt.xticks(())
plt.yticks(())
#添加图形标题
plt.title('五大洲GDP占比')
#显示图形
plt.show()
#绘制地图
import pygal
import pygal_maps_world.maps
from pygal.style import RotateStyle
from pygal.style import LightColorizedStyle
#创建一个字典
cy_GDP={}
cy_GDP1,cy_GDP2,cy_GDP3={},{},{}
#将df1中gdp存入cy_GDP
cy_GDP=df1['gdp']
for c,GDP in cy_GDP.items():
if GDP<2e12:
cy_GDP1[c]=GDP
elif GDP<2e13:
cy_GDP2[c]=GDP
else:
cy_GDP3[c]=GDP
wm_style=RotateStyle('#EE2C2C',base_style=LightColorizedStyle)
wm = pygal_maps_world.maps.World(style=wm_style)
#增加标签
wm.add('0-2billion',cy_GDP1)
wm.add('2billion-1trillion',cy_GDP2)
wm.add('>1trillion',cy_GDP3)
wm.render_to_file('D:\world_GDP.svg')
plt.show()
4.根据数据之间的关系,分析两个变量之间的相关系数,画出散点图,并建立变量之间的回归方程( 一元或多元) 。
#2017-2020年世界各国GDP总值
df3=datas.groupby('year')[['gdp']].sum().reset_index()
df3
在2019年前,随着年份的增加,世界各国GDP值逐渐增加;2019年后,GDP值有所下降。
import seaborn as sns
#绘制回归图
sns.regplot(x=df['year'],y=df3['gdp'],data=df3)
flag,axes=plt.subplots(2,2)
#默认的效果图
sns.regplot(x=df3['year'],y=df3['gdp'],ax=axes[0][0])
#ci参数可以控制是否显示置信区间
sns.regplot(x=df3['year'],y=df3['gdp'],ci=None,ax=axes[0][1])
#mark参数可以设置数据点格式,color参数可以设置颜色
sns.regplot(x=df3['year'],y=df3['gdp'],color='g',marker='+',ax=axes[1][0])
#fit_reg参数可以控制是否显示拟合的直线
sns.regplot(x=df3['year'],y=df3['gdp'],color='r',marker='*',fit_reg=False,ax=axes[1][1])
#显示图像
plt.show()
变量之间的回归方程:y=8.55e+13
5.数据持久化
将数据进行保存和备份,以便后期进行修改和查阅。
6.
将以上各部分的代码汇总,附上完整程序代码
import requests
from lxml import etree
import pandas as pd
import matplotlib.pyplot as plt
import warnings
#忽略警告
warnings.filterwarnings("ignore")
#显示中文
plt.rcParams['font.sans-serif'] = ['SimHei']
#浏览器的UA
headers = {'User-Agent':'Mozilla/4.0 (compatible; MSIE 7.0; AOL 9.5; AOLBuild 4337.35; Windows NT 5.1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)'}
def get_data(url):
for n in range(20):
try:
dfs = requests.get(url,headers = headers,timeout = 5,verify=False).text
except Exception:
pass
else:
break
return dfs
#新建表格存储数据
datas = pd.DataFrame()
#循环爬取每一年的数据
for year in range(2017,2021):
print(year)
#构造链接
url1 = 'https://www.kylc.com/stats/global/yearly/g_gdp/'+str(year)+'.html'
#获取网页源码
df1 = get_data(url1)
#转化为HTML格式数据
html1 = etree.HTML(df1)
#提取对应数据
df1 = html1.xpath('//tbody/tr/td[2]/text()')
df2 = html1.xpath('//tbody/tr/td[3]/text()')
df3 = html1.xpath('//tbody/tr/td[4]/text()')
df4 = html1.xpath('//tbody/tr/td[5]/text()')
#找到不要的数据标签
index1 = df1.index('全世界')
#删除数据
del df1[index1]
del df3[index1]
del df4[index1]
index2 = df1.index('欧盟地区')
del df1[index2]
del df3[index2]
del df4[index2]
print(df1)
print(df2)
print(df3)
print(df4)
#存入dataframe表格
data = pd.DataFrame()
data['国家'] = df1
data['洲'] = df2
data['GDP'] = df3
data['占世界%'] = df4
data['year'] = year
#合并到大表格
datas = pd.concat([datas,data])
#保存到csv中
datas.to_csv('D:/数据.csv')
#读取csv文件
df=pd.read_csv('D:/数据.csv')
#显示数据
df
#清洗数据
datas['gdp'] = datas['GDP'].map(lambda x:float(x.split('(')[-1].split(')')[0].replace(',','')))
#去掉占比的百分号
datas['占比'] = datas['占世界%'].map(lambda x:float(x.replace('%','')))
#去掉不要的列
datas.drop(['GDP','占世界%'],axis = 1,inplace = True)
#存入csv
datas.to_csv('D:/清洗后数据.csv')
#读取csv文件
d=pd.read_csv('D:/清洗后数据.csv')
#显示数据
d
#数据可视化
df = datas.groupby('year')[['gdp']].sum().reset_index()
#显示数据
df
#绘制折线图,透明度为0.8,线条宽度为3
plt.plot(df['year'],df['gdp'],alpha=0.8,linewidth = 3)
#添加x轴标签
plt.xlabel("year",fontsize=14)
#增加y轴标签
plt.ylabel('gdp',fontsize=14)
#增加标题标签
plt.title('每年全球GDP变化')
# 生成网格
plt.grid()
#显示图像
plt.show()
#绘制水平柱状图
plt.barh(d['year'],d['gdp'],label='2017年-2020年世界全国GDP值')
#显示图像
plt.show()
#看看历年gdp均值排名前10的国家
df1 = datas.groupby('国家')[['gdp']].mean().reset_index().sort_values(by = 'gdp',ascending = False).iloc[:20]
#显示数据
df1
#创建figure对象,宽10英寸,高6英寸
plt.figure(figsize = (10,6))
#绘制柱状图,透明度为0.8
plt.bar(df1['国家'],df1['gdp'],alpha=0.8)
#添加x轴标签
plt.xlabel("国家",fontsize=14)
#添加y轴标签
plt.ylabel('gdp',fontsize=14)
#添加标题标签
plt.title('GDP均值国家排名TOP10')
#生成网格
plt.grid()
#x轴标签旋转90度
plt.xticks(rotation=90)
#显示图像
plt.show()
#绘制散点图
plt.scatter(df1['国家'],df1['gdp'],color='k',s=25,marker="o")
#显示图像
plt.show()
#绘制直方图
import seaborn as sns
sns.distplot(df1['gdp'])
fig,axes=plt.subplots(2,2)
#默认绘图效果
sns.distplot(df1['gdp'],ax=axes[0][0])
#kde=False:不显示密度曲线
sns.distplot(df1['gdp'],kde=False,ax=axes[0][1])
#rug=True:在坐标轴上添加地毯图
sns.distplot(df1['gdp'],rug=True,ax=axes[1][0])
#调节vertical\hist_kws和kde_kws参数,改变直方图方向、坐标轴和密度曲线颜色
sns.distplot(df1['gdp'],vertical=True,hist_kws={'color':'blue','label':'hist'},kde_kws = {'color':'red','label':'KDE'},ax=axes[1][1])
#显示图像
plt.show()
#五大洲历年GDP总和
df2 = datas.groupby('洲')[['gdp']].sum().reset_index()
#五大洲总占比
df2['占比'] = df2['gdp']/df2['gdp'].sum()
#显示数据
df2
#绘制小提琴
sns.violinplot(df2['gdp'])
#显示图像
plt.show()
#准备数据
values = list(df2['占比'])
#准备标签
labels = list(df2['洲'])
#使用自定义颜色
colors = ['red','pink','magenta','purple','orange']
#将横、纵坐标轴标准化处理,保证饼图是一个正圆,否则为椭圆
plt.axes(aspect='equal')
#控制X轴和Y轴的范围(用于控制饼图的圆心、半径)
plt.xlim(0,8)
plt.ylim(0,8)
#不显示右边框
plt.gca().spines['right'].set_color('none')
#不显示上边框
plt.gca().spines['top'].set_color('none')
#不显示左边框
plt.gca().spines['left'].set_color('none')
#不显示下边框
plt.gca().spines['bottom'].set_color('none')
#绘制饼图
plt.pie(
#绘制数据
x=values,
#添加编程语言标签
labels=labels,
#设置自定义填充色
colors=colors,
#设置百分比的格式,保留3位小数
autopct='%.1f%%',
#设置百分比标签和圆心的距离
pctdistance=0.5,
#设置标签和圆心的距离
labeldistance=1.2,
#设置饼图的初始角度
startangle=180,
#设置饼图的圆心(相当于X轴和Y轴的范围)
center=(4,4),
#设置饼图的半径(相当于X轴和Y轴的范围)
radius=3.8,
#是否为逆时针方向,False表示顺时针方向
counterclock= False,
#设置饼图内外边界的属性值
wedgeprops= {'linewidth':1,'edgecolor':'green'},
#设置文本标签的属性值
textprops= {'fontsize':12,'color':'black'},
#设置文本标签的属性值
frame=1
)
#不显示X轴的刻度值
plt.xticks(())
#不显示Y轴的刻度值
plt.yticks(())
#添加图形标题
plt.title('五大洲GDP占比')
#显示图形
plt.show()
#绘制地图
import pygal
import pygal_maps_world.maps
from pygal.style import RotateStyle
from pygal.style import LightColorizedStyle
#创建一个字典
cy_GDP={}
cy_GDP1,cy_GDP2,cy_GDP3={},{},{}
#将df1中gdp存入cy_GDP
cy_GDP=df1['gdp']
#遍历
for c,GDP in cy_GDP.items():
if GDP<2e12:
cy_GDP1[c]=GDP
elif GDP<2e13:
cy_GDP2[c]=GDP
else:
cy_GDP3[c]=GDP
wm_style=RotateStyle('#EE2C2C',base_style=LightColorizedStyle)
wm = pygal_maps_world.maps.World(style=wm_style)
#增加标签
wm.add('0-2billion',cy_GDP1)
wm.add('2billion-1trillion',cy_GDP2)
wm.add('>1trillion',cy_GDP3)
wm.render_to_file('D:\world_GDP.svg')
#D盘增加世界地图文件
plt.show()
#2017-2020年世界各国GDP总值
df3=datas.groupby('year')[['gdp']].sum().reset_index()
#显示数据
df3
import seaborn as sns
#绘制回归图
sns.regplot(x=df['year'],y=df3['gdp'],data=df3)
flag,axes=plt.subplots(2,2)
#默认的效果图
sns.regplot(x=df3['year'],y=df3['gdp'],ax=axes[0][0])
#ci参数可以控制是否显示置信区间
sns.regplot(x=df3['year'],y=df3['gdp'],ci=None,ax=axes[0][1])
#mark参数可以设置数据点格式,color参数可以设置颜色
sns.regplot(x=df3['year'],y=df3['gdp'],color='g',marker='+',ax=axes[1][0])
#fit_reg参数可以控制是否显示拟合的直线
sns.regplot(x=df3['year'],y=df3['gdp'],color='r',marker='*',fit_reg=False,ax=axes[1][1])
#显示图像
plt.show()
五、总结
1.经过对主题数据的分析与可视化,可以得到哪些结论?是否达到预期的目标?
(1)疫情前世界全球经济GDP都处于快速增长情况,但疫情年全球经济GDP开始逐渐下降。
往年GDP平均水平比较高的国家由:美国、中国、日本、德国、英国。
五大洲GDP排名为:美洲、亚洲、欧洲、非洲、大洋洲
(2)首先通过request爬取世界各国数据,其次用csv文件保存数据,然后读取数据进行可视化。根据分析达到了预期的目标。
2.在完成此设计过程中,得到哪些收获?以及要改进的建议?
(1)让我对matplotlib等库有深刻的了解,让我体会到大数据的魅力。其次第一次使用python完成一次实验,让我充满成就感,激发了我对python学习的兴趣。
(2)在使用matplotlib库进行数据可视化时,没有进一步的思考,没有增加一些其他元素让图像更加美观直接,导致最后出来的图像过于单一,这是我需要改进的地方。
标签:GDP,gdp,plt,df1,df3,爬取,2020,year From: https://www.cnblogs.com/nash220/p/17002912.html