社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  Python

​十一长假来袭,用 Python 偷偷告诉你全国哪些景点最值得去

高效运维 • 4 年前 • 453 次点击  

据文化和旅游部消息称,预计 2019 年“十一”旅游人次有望达到近 8 亿。

#假期或有近 8 亿人次出游#这个话题还冲上了微博热搜榜。

我仿佛已经看到了假期景区人山人海的画面!
左思右想,最后落脚到小长假的旅游上,能否用网络爬虫看看,十一长假哪些城市最堵?哪些景区最热门?
小编爬取了去哪儿网上面的6000多个景点数据,包含景点评级、热度、销量等等数据,汇总成这篇出游参考指南。
爬虫
爬虫继续用的是小编最近的心头爱selenium,用法可以参考“爬虫神器selenium之猫眼电影榜单实例”。打开去哪儿网站,右键,分析网页。



我们需要的数据非常的清晰:



话不多说,只要定位到自己想要的信息,那么代码非常简单。
1from tqdm import tqdm
2import time
3from selenium import webdriver
4from selenium.common.exceptions import TimeoutException, WebDriverException
5import pandas as pd
6import numpy as np
7position = ["北京","天津","上海","重庆","河北","山西","辽宁","吉林","黑龙江","江苏","浙江","安徽","福建","江西","山东","河南","湖北","湖南","广东","海南","四川","贵州","云南","陕西","甘肃","青海","台湾","内蒙古","广西","西藏","宁夏","新疆","香港","澳门"]
8
9name,level,hot,address,num=[],[],[],[],[]
10def get_one_page(key,page):
11 try:
12 #打开浏览器窗口
13 option_chrome = webdriver.ChromeOptions()
14 option_chrome.add_argument('--headless')
15
16 driver = webdriver.Chrome(chrome_options=option_chrome)
17 time.sleep(1)
18
19 url = "http://piao.qunar.com/ticket/list.htm?keyword="+str(key)+"&region=&from=mpl_search_suggest&page="+str(page)
20 driver.get(url)
21 infor = driver.find_elements_by_class_name("sight_item")
22 for i in range(len(infor)):
23 #获取景点名字
24 name.append(infor[i].find_element_by_class_name("name").text)
25 #获取景点评级
26 try:
27 level.append(infor[i].find_element_by_class_name("level").text)
28 except:
29 level.append("")
30 #获取景点热度
31 hot.append(infor[i].find_element_by_class_name("product_star_level").text[3:])
32 #获取景点地址
33 address.append(infor[i].find_element_by_class_name("area").text)
34 #获取景点销量
35 try:
36 num.append(infor[i].find_element_by_class_name("hot_num").text)
37 except:
38 num.append(0)
39
40 driver.quit()
41 return
42 except TimeoutException or WebDriverException:
43 return get_one_page()
44
45for key in tqdm(position):
46 print ("正在爬取{}".format(key))
47 #取前10页
48 for page in range(1,14):
49 print ("正在爬取第{}页".format(page))
50 get_one_page(key,page)
51
52sight = {'name': name, 'level': level, 'hot': hot, 'address': address, 'num':num}
53sight = pd.DataFrame(sight, columns=['name', 'level', 'hot', 'address', 'num'])
54sight.to_csv("sight.csv",encoding="utf_8_sig")
本文仅爬取国内的数据,由于景点数据众多,每个省份仅取了前13页。获得景点个数6630个。
数据可视化
热门景区top30:



大熊猫不愧为国宝,最热门就是它。其次是故宫,郑州动物园,峨眉山,秦始皇兵马俑等等。因为小编没有去过多少地方玩,也不知道为啥郑州动物园能排到第三,大家知道的可以告诉小编一下它的特色吗?
热力图:
热力图根据省份和城市分别作图,其次在根据销量和热度两类图,这里采用的是“Python调用高德地图API实现经纬度换算、地图可视化”一文的方式,调用高德地图API完成。
首先是省份和景区热度:



然后是省份和销量:


接下来是城市和景区热度:


最后是城市和景区销量:


值得注意的是,城市和销量一图热力范围不明显,原因为景区之间销量天差地别,一些太少的的统计下来,作图非常的不明显了。若大家不喜欢用高德地图API作图,那么"人生苦短,我要用pyecharts画图"的方法也非常适合做热力图,比如这里小编做了一张省份和销量的图:


综合来看,北京,四川,沿海等地都是旅游的热门省份。建议大家尽量避免去这些省份游玩。
可视化代码:
1data = pd.read_csv("sight.csv")
2data = data.fillna(0)
3data = data.drop(columns=['Unnamed: 0'])
4
5#将地址分为省,市,区
6data["address"] = data["address"].apply(lambda x: x.replace("[","").replace("]",""))
7data["province"] = data["address"].apply(lambda x: x.split("·")[0])
8data["city"] = data["address"].apply(lambda x: x.split("·")[1])
9data["area"] = data["address"].apply(lambda x: x.split("·")[-1])
10
11#销量最多的前30景点
12num_top = data.sort_values(by = 'num',axis = 0,ascending = False).reset_index(drop=True)
13import seaborn as sns
14import matplotlib.pyplot as plt
15plt.rcParams['font.sans-serif'] = ['Microsoft YaHei']#指定默认字体
16plt.rcParams['axes.unicode_minus'] =False # 解决保存图像是负号'-'显示为方块的问题
17sns.set(font='SimHei') # 解决Seaborn中文显示问题
18sns.set_context("talk")
19fig = plt.figure(figsize=(15,10))
20sns.barplot(num_top["name"][:30],num_top["num"][:30])
21plt.xticks(rotation=90)
22fig.show()
23
24#省份与景区评级
25data["level_sum"] =1
26var = data.groupby(['province', 'level']).level_sum.sum()
27var.unstack().plot(kind='bar',figsize=(35,10), stacked=False, color=['red', 'blue','green','yellow'])
28
29#根据省、市统计销量和
30pro_num = data.groupby(['province']).agg('sum').reset_index()
31city_num = data.groupby(['city']).agg('sum').reset_index()
32#基于数据做热力图
33import requests
34def transform(geo):
35 key = 'bb9a4fae3390081abfcb10bc7ed307a6'
36 url="http://restapi.amap.com/v3/geocode/geo?key=" +str(key) +"&address=" + str(geo)
37 response = requests.get(url)
38 if response.status_code == 200:
39 answer = response.json()
40 try:
41 loc = answer['geocodes'][0]['location']
42 except:
43 loc = 0
44 return loc
45
46pro_num["lati"] = pro_num["province"].apply(lambda x: transform(x))
47city_num["lati"] = city_num["city"].apply(lambda x: transform(x))
48pro_num.to_csv("pro_num.csv",encoding="utf_8_sig")
49city_num.to_csv("city_num.csv",encoding="utf_8_sig")
50
51from pyecharts import Map
52map=Map("省份景点销量热力图", title_color="#fff", title_pos="center", width=1200, height=600, background_color='#404a59')
53map.add("",pro_num["province"], pro_num["num"], maptype="china", visual_range=[5000, 80000], is_visualmap=True, visual_text_color='#000', is_label_show=True)
54map.render(path="pro_num.html")
55map=Map("省份景点热度热力图", title_color="#fff", title_pos="center", width=1200, height=600, background_color='#404a59')
56map.add("",pro_num["province"], pro_num["hot"], maptype="china", visual_range=[25,80], is_visualmap=True, visual_text_color='#000', is_label_show=True)
57map.render(path="pro_hot.html")
58
59#人少的5A景点,4A景点,3A景点
60top_5A = data[data["level"] == "5A景区"].sort_values(by = 'num',axis = 0,ascending = True).reset_index(drop=True)
61top_4A = data[data["level"] == "4A景区"].sort_values(by = 'num',axis = 0,ascending = True).reset_index(drop=True)
62top_3A = data[data["level"] == "3A景区"].sort_values(by = 'num',axis = 0,ascending = True).reset_index(drop=True)
63fig = plt.figure(figsize=(15,15))
64plt.pie(top_5A["num"][:15],labels=top_5A["name"][:15],autopct='%1.2f%%')
65plt.title("人少的5A景区")
66plt.show()
67fig = plt.figure(figsize=(15,15))
68ax = sns.barplot(top_4A["hot"][:15],top_4A["name"][:15])
69ax.set_title("人少的4A景区")
70fig.show()
71fig = plt.figure(figsize=(15,10))
72ax = sns.barplot(top_3A["name"][:15],top_3A["hot"][:15])
73ax.set_title("人少的3A景区")
74plt.xticks(rotation=90)
75fig.show()

最前沿的技术

最纯粹的分享

最资深的讲师

最典型的落地案例

就在 GOPS 2019 · 上海站

更多 GOPS 2019 上海站精彩,点击阅读原文

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/46104
 
453 次点击