写在前面
在网易云课堂看到城市数据团大鹏老师讲的《Python数据可视化利器:Pyecharts!》[传送门],于是把前一篇南京的景点数据做一个可视化。
1、还是去哪儿网景点爬取
具体可以看之前的帖子
《python爬取景点数据看该去哪里玩——南京篇》
我把代码拿过来按照需要调整一下,只要主要评价数据就行
import requests
from bs4 import BeautifulSoup
import numpy as np
import pandas as pd
import time
#创建函数,获取页面数据
def get_urls(ui,n): #ui:地址,n:页码数
urllst = []
for i in range(1,n+1):
urllst.append(ui+str(i))
return urllst
#获得每个页面信息
def get_onepage_data(u): #u:网址
r = requests.get(u)
soup = BeautifulSoup(r.text, 'lxml')
infor = soup.find('ul',class_ = "list_item clrfix").find_all('li')
data_jd = []
data_link = []
for i in infor:
dic = {}
dic_link = {}
#dic['lat'] = i['data-lat']
#dic['lng'] = i['data-lng']
dic['景点名称'] = i.find('span', class_="cn_tit").text
dic['攻略提到数量'] = i.find('div', class_="strategy_sum").text
dic['点评数量'] = i.find('div', class_="comment_sum").text
dic['景点排名'] = i.find('span', class_="ranking_sum").text
dic['驴友去过'] = i.find('span', class_="sum").text.split('%')[0]
dic['星级'] = i.find('span', class_="cur_star")['style'].split(':')[1].split('%')[0]
#dic['描述'] = i.find('div', class_="desbox").text
#dic['链接'] = i.find('a')['href']
data_jd.append(dic)
return data_jd
#获得所有网页信息
def get_all_data(urls): #urls 网址列表
data_list= []
for i in urls:
data_list.extend(get_onepage_data(i))
#print('成功采集%i个景点数据' % len(data_list))
df = pd.DataFrame(data_list) #导入pandas的DataFrame
df.index = df['景点名称']
del df['景点名称']
return df
#数据字符转数字,以计算处理
def data_collation(df):
#df['lng'] = df['lng'].astype(np.float)
#df['lat'] = df['lat'].astype(np.float)
df['点评数量'] = df['点评数量'].astype(np.int)
df['攻略提到数量'] = df['攻略提到数量'].astype(np.int)
df['驴友去过'] = df['驴友去过'].astype(np.int)
df['星级'] = df['星级'].astype(np.int)
df.fillna(value = 0,inplace = True) #填充空值,如果列是lnt类型就0;如果是str就用nan
return df
# 筛选综合得分前n名的数据
def data_top(urls,n): # 前n个数据
df = get_all_data(urls)
df = data_collation(df)
# 构建函数实现字段标准化,标准分
cols = ['攻略提到数量','星级','点评数量']
for col in cols:
df[col + '_b'] = round((df[col] - df[col].min())/(df[col].max() - df[col].min())*100,2)
#由驴友去过比例得分+攻略提到数量得分+星级得分+点评数得分,每项均为0-100分
df['综合得分'] = df['驴友去过']+df['攻略提到数量_b']+df['星级_b']+df['点评数量_b']
top_n = df.sort_values(by = '综合得分', ascending=False).iloc[:n]
return top_n
if __name__=="__main__":
start_time = time.time()
urls = get_urls('https://travel.qunar.com/p-cs299861-nanjing-jingdian-1-',5) #链接及页数
top30_data = data_top(urls,30) # 前30的数据
end_time1 = time.time()
print ("爬取基本数据,耗时:",end_time1 - start_time)
爬取基本数据,耗时: 1.3800303936004639
2、交互式可视化
一种方法就是把这个数据里的’攻略提到数量’、‘星级’、'点评数量’做一个可视化
加载pyecharts,没有的可以在控制台用pip install pyecharts
先安装
from pyecharts.charts import Bar
from pyecharts.globals import ThemeType
from pyecharts import options as opts
bar = (
#条状图,定义大小样式,样式可以官方文件里找到各种样式
Bar(opts.InitOpts(width = '1000px',height = '500px',theme=ThemeType.INFOGRAPHIC))
#增加横轴,标注用景点名称,tolist()将pandas数据转成list
.add_xaxis(top_n.index.tolist())
#增加纵轴,这里有三种数据
.add_yaxis('点评数量',top_n['点评数量'].tolist())
.add_yaxis('攻略提到数量',top_n['攻略提到数量'].tolist())
.add_yaxis('星级',top_n['星级'].tolist())
#全局属性,加这个工具箱和缩略轴还比较好用
.set_global_opts(
toolbox_opts = opts.ToolboxOpts(is_show = True), # 设置工具箱
datazoom_opts= [opts.DataZoomOpts(range_start=10, range_end=80,is_zoom_lock=False)], # 设置slider缩略轴
)
#局部属性,加了一个最大值最小值显示,平均值
.set_series_opts(
markpoint_opts=opts.MarkPointOpts(
data=[
opts.MarkPointItem(type_="max", name="最大值"),
opts.MarkPointItem(type_="min", name="最小值"),
]
),
markline_opts = opts.MarkLineOpts(
data = [
opts.MarkLineItem(type_ = 'average', name= '平均值')
]
)
)
)
bar.render_notebook() #就这么简单
整体出来就是下面这样:
其中几个数据可以分别显示,动画演示
调整和拉动缩放轴的效果,动画演示