2017-2020年世界各国GDP数据爬取

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

该页面由divtdtr等组成的世界各国GDPhtml页面程序代码。

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_kwskde_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={},{},{}

#df1gdp存入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_kwskde_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={},{},{}

#df1gdp存入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库进行数据可视化时,没有进一步的思考,没有增加一些其他元素让图像更加美观直接,导致最后出来的图像过于单一,这是我需要改进的地方。

 

posted @ 2022-12-24 15:18  zhang14  阅读(895)  评论(0)    收藏  举报