- 使用python requests库爬取福布斯排行榜数据存放到本地excel文件,并通过matplotlab将数据进行分析和可视化
- 原网页如下所示 https://www.phb123.com/renwu/fuhao/shishi_1.html
- 保存的excel数据如下所示
- 福布斯前十排行的数据可视化效果
- 各个国家上榜人数所占比例的统计与可视化
- 爬取网页数据解析为一个list集合的代码
## 读取一页的数据
def loaddata(url):
from bs4 import BeautifulSoup
import requests
headers = {
'User-Agent':'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_3) AppleWebKit/537.36 (KHTML, like Gecko) '
'Chrome/72.0.3626.121 Safari/537.36'
}
f = requests.get(url,headers=headers) #Get该网页从而获取该html内容
soup = BeautifulSoup(f.content, "lxml") #用lxml解析器解析该网页的内容, 好像f.text也是返回的html
# print(f.content.decode()) #尝试打印出网页内容,看是否获取成功
ranktable = soup.find_all('table',class_="rank-table" )[0] #获取排行榜表格
trlist = ranktable.find_all('tr') #获取表格中所有tr标签
trlist.pop(0) #去掉第一个元素
persionlist = []
for tr in trlist:
persion = {}
persion['num'] = tr.find_all('td')[0].string #编号
persion['name'] = tr.find_all('td')[1].p.string #名称
persion['money'] = tr.find_all('td')[2].string #财产
persion['company'] = tr.find_all('td')[3].string #企业
persion['country'] = tr.find_all('td')[4].a.string #国家
persionlist.append(persion)
print("页面"+url+"爬取成功")
return persionlist
## 读取所有福布斯排行榜数据
def loadalldata():
alldata = []
for i in range(1,16,1):
url = "https://www.phb123.com/renwu/fuhao/shishi_"+str(i)+".html"
data = loaddata(url)
alldata = alldata + data
return alldata
- 将爬取的list集合保存到本地excel文件的代码
## 将爬取的数据保存到文件
def savedata(path,persionlist):
import xlwt
workbook = xlwt.Workbook()
worksheet = workbook.add_sheet('test')
worksheet.write(0, 0, '排名')
worksheet.write(0, 1, '姓名')
worksheet.write(0, 2, '财富')
worksheet.write(0, 3, '企业')
worksheet.write(0, 4, '国家')
for i in range(1,len(persionlist)+1,1):
worksheet.write(i, 0, persionlist[i-1]['num'])
worksheet.write(i, 1, persionlist[i-1]['name'])
worksheet.write(i, 2, persionlist[i-1]['money'])
worksheet.write(i, 3, persionlist[i-1]['company'])
worksheet.write(i, 4, persionlist[i-1]['country'])
workbook.save(path)
print("数据保存成功:"+path)
- 读取excel文件数据进行分析绘制条形图和饼状图的代码
## 取出排行榜前十的姓名和财富数据 以两个list返回
def loadtop10(path):
import xlrd
book = xlrd.open_workbook(path)
sheet1 = book.sheets()[0]
namelist = sheet1.col_values(1)
moneylist = sheet1.col_values(2)
namelist = namelist[1:11]
moneylist = moneylist[1:11]
moneylist2 = []
for a in moneylist:
a = int(a[0:-3])
moneylist2.append(a)
print("取出排行榜前十的姓名和财富数据")
print(namelist)
print(moneylist2)
return namelist,moneylist2
## 统计排行榜中每个国家的上榜人数 以字典list返回
def countcountrynum(path):
import xlrd
book = xlrd.open_workbook(path)
sheet1 = book.sheets()[0]
countrylist = sheet1.col_values(4)[1:-1]
print(countrylist)
countryset = list(set(countrylist))
dictlist = []
for country in countryset:
obj = {"name":country,"count":0}
dictlist.append(obj)
## 统计出每个国家对应的数量
for obj in dictlist:
for a in countrylist:
if obj['name'] == a:
obj['count'] = obj['count'] + 1
print(dictlist)
## 将dictlist排序 数量多的放前面 8 5 6 9 3 2 4
for i in range(0,len(dictlist),1):
for j in range(0,len(dictlist)-i-1,1):
if dictlist[j]['count'] < dictlist[j+1]['count']:
temp = dictlist[j]
dictlist[j] = dictlist[j+1]
dictlist[j+1] = temp
dictlist2 = dictlist[0:5]
set2 = []
for a in dictlist2:
set2.append(a['name'])
othercount = 0;
for a in dictlist:
if a['name'] not in set2:
othercount = othercount + 1
dictlist2.append({"name":"其他","count":othercount})
print('获取排行榜中每个国家的上榜人数')
print(dictlist2)
return dictlist2
## 绘制条形图和饼状图
def drow():
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei'] # 设置中文字体
plt.figure('福布斯前十榜',figsize=(15,5))
## 读取福布斯排行榜前十的数据
listx,listy = loadtop10('rank.xls')
plt.title('福布斯前十榜', fontsize=16)
plt.xlabel('人物', fontsize=14)
plt.ylabel('金额/亿美元', fontsize=14)
plt.tick_params(labelsize=10)
plt.grid(linestyle=':', axis='y')
a = plt.bar(listx, listy, color='dodgerblue', label='Apple', align='center')
# 设置标签
for i in a:
h = i.get_height()
plt.text(i.get_x() + i.get_width() / 2, h, '%d' % int(h), ha='center', va='bottom')
## -------------------------------------------------------------------------
dictlist = countcountrynum("rank.xls")
plt.figure('各国家上榜人数所占比例')
labels = []
sizes = []
for a in dictlist:
labels.append(a['name'])
sizes.append(a['count'])
explode = (0.1, 0, 0, 0, 0, 0)
plt.pie(sizes, explode=explode, labels=labels, autopct='%1.1f%%', shadow=False, startangle=150)
plt.title("各国家上榜人数所占比例", fontsize=16)
plt.axis('equal') # 该行代码使饼图长宽相等
plt.show()
## 读取一页的数据
def loaddata(url):
from bs4 import BeautifulSoup
import requests
headers = {
'User-Agent':'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_3) AppleWebKit/537.36 (KHTML, like Gecko) '
'Chrome/72.0.3626.121 Safari/537.36'
}
f = requests.get(url,headers=headers) #Get该网页从而获取该html内容
soup = BeautifulSoup(f.content, "lxml") #用lxml解析器解析该网页的内容, 好像f.text也是返回的html
# print(f.content.decode()) #尝试打印出网页内容,看是否获取成功
ranktable = soup.find_all('table',class_="rank-table" )[0] #获取排行榜表格
trlist = ranktable.find_all('tr') #获取表格中所有tr标签
trlist.pop(0) #去掉第一个元素
persionlist = []
for tr in trlist:
persion = {}
persion['num'] = tr.find_all('td')[0].string #编号
persion['name'] = tr.find_all('td')[1].p.string #名称
persion['money'] = tr.find_all('td')[2].string #财产
persion['company'] = tr.find_all('td')[3].string #企业
persion['country'] = tr.find_all('td')[4].a.string #国家
persionlist.append(persion)
print("页面"+url+"爬取成功")
return persionlist
## 读取所有福布斯排行榜数据
def loadalldata():
alldata = []
for i in range(1,16,1):
url = "https://www.phb123.com/renwu/fuhao/shishi_"+str(i)+".html"
data = loaddata(url)
alldata = alldata + data
return alldata
## 将爬取的数据保存到文件
def savedata(path,persionlist):
import xlwt
workbook = xlwt.Workbook()
worksheet = workbook.add_sheet('test')
worksheet.write(0, 0, '排名')
worksheet.write(0, 1, '姓名')
worksheet.write(0, 2, '财富')
worksheet.write(0, 3, '企业')
worksheet.write(0, 4, '国家')
for i in range(1,len(persionlist)+1,1):
worksheet.write(i, 0, persionlist[i-1]['num'])
worksheet.write(i, 1, persionlist[i-1]['name'])
worksheet.write(i, 2, persionlist[i-1]['money'])
worksheet.write(i, 3, persionlist[i-1]['company'])
worksheet.write(i, 4, persionlist[i-1]['country'])
workbook.save(path)
print("数据保存成功:"+path)
## 取出排行榜前十的姓名和财富数据 以两个list返回
def loadtop10(path):
import xlrd
book = xlrd.open_workbook(path)
sheet1 = book.sheets()[0]
namelist = sheet1.col_values(1)
moneylist = sheet1.col_values(2)
namelist = namelist[1:11]
moneylist = moneylist[1:11]
moneylist2 = []
for a in moneylist:
a = int(a[0:-3])
moneylist2.append(a)
print("取出排行榜前十的姓名和财富数据")
print(namelist)
print(moneylist2)
return namelist,moneylist2
## 统计排行榜中每个国家的上榜人数 以字典list返回
def countcountrynum(path):
import xlrd
book = xlrd.open_workbook(path)
sheet1 = book.sheets()[0]
countrylist = sheet1.col_values(4)[1:-1]
print(countrylist)
countryset = list(set(countrylist))
dictlist = []
for country in countryset:
obj = {"name":country,"count":0}
dictlist.append(obj)
## 统计出每个国家对应的数量
for obj in dictlist:
for a in countrylist:
if obj['name'] == a:
obj['count'] = obj['count'] + 1
print(dictlist)
## 将dictlist排序 数量多的放前面 8 5 6 9 3 2 4
for i in range(0,len(dictlist),1):
for j in range(0,len(dictlist)-i-1,1):
if dictlist[j]['count'] < dictlist[j+1]['count']:
temp = dictlist[j]
dictlist[j] = dictlist[j+1]
dictlist[j+1] = temp
dictlist2 = dictlist[0:5]
set2 = []
for a in dictlist2:
set2.append(a['name'])
othercount = 0;
for a in dictlist:
if a['name'] not in set2:
othercount = othercount + 1
dictlist2.append({"name":"其他","count":othercount})
print('获取排行榜中每个国家的上榜人数')
print(dictlist2)
return dictlist2
## 绘制条形图和饼状图
def drow():
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei'] # 设置中文字体
plt.figure('福布斯前十榜',figsize=(15,5))
## 读取福布斯排行榜前十的数据
listx,listy = loadtop10('rank.xls')
plt.title('福布斯前十榜', fontsize=16)
plt.xlabel('人物', fontsize=14)
plt.ylabel('金额/亿美元', fontsize=14)
plt.tick_params(labelsize=10)
plt.grid(linestyle=':', axis='y')
a = plt.bar(listx, listy, color='dodgerblue', label='Apple', align='center')
# 设置标签
for i in a:
h = i.get_height()
plt.text(i.get_x() + i.get_width() / 2, h, '%d' % int(h), ha='center', va='bottom')
## -------------------------------------------------------------------------
dictlist = countcountrynum("rank.xls")
plt.figure('各国家上榜人数所占比例')
labels = []
sizes = []
for a in dictlist:
labels.append(a['name'])
sizes.append(a['count'])
explode = (0.1, 0, 0, 0, 0, 0)
plt.pie(sizes, explode=explode, labels=labels, autopct='%1.1f%%', shadow=False, startangle=150)
plt.title("各国家上榜人数所占比例", fontsize=16)
plt.axis('equal') # 该行代码使饼图长宽相等
plt.show()
if __name__ == '__main__':
## 爬取数据
# data = loadalldata()
## 保存数据
# savedata("rank.xls",data)
## 展示数据
drow()