抖音引爆长沙
技术宅告诉你哪个景点最火!
抖音
带火了西安的摔碗酒
鼓浪屿的土耳其冰激凌
重庆的立体城市···
最近
马可入驻了抖音
#你是湖南人不#
这一话题引爆抖音
一时间
恰得苦霸得蛮耐得烦的长沙人
疯狂地拍摄长沙各大景点发到抖音平台
岳麓山、橘子洲、太平街…
于是
在三十多度的高温下
长沙的景点开始“沦陷”
夜晚也依然人潮拥挤
抖友们纷纷表示
不要再刷湖南了
我们赖以生存的——
小龙虾、臭豆腐、大香肠都要涨价啦!
吃不起了,嗦不起了!
竟然——
启发了某些穷苦大学生的生意头脑
今天放假
对话如下
【妹坨:歪,噶向冒钱用了,有冇得什么赚钱的路子。
满锅:你看现在抖音上面长沙那么火,天气国热八热,卖冰棒卖矿泉水克撒。】
【妹坨:你莫急我啦,我真的克,哪里人最多咯?
满哥:国还不易得,我搞把你看咯】
于是
便有了接下来的一幕
满锅的技术宅力量!
如果能知道各个景点的搜索热度,再画出热力图,不就很直观的看到哪里人多了?
下是python爬虫爬取长沙热门景点绘制热力图全解,附完整代码。
(PS:以下代码以Python3.6编写, 其中import的包有urllib.request、urllib、 lxml.etree、re、requests、time、json这些,如果代码运行报错了不妨检查一下这些哦.)
如何用python爬取长沙热门景点再绘制热力图呢?
①首先,要知道搜索热度,当然是去旅游出行网站找啦,分析去哪儿景点页的网址可得出链接结构:http://piao.qunar.com/ticket/list.htm?keyword=搜索地点®ion=&from=mpl_search_suggest&page=页数
我们可以看到,通过改变传参页数,就达到了翻页的目的。
好的,既然知道了页面结构了,那就上爬虫逐页爬取吧!
②逐页爬取
1. #此函数用于获取景点名称和热度信息
2. def getList():
3. place = "changsh"
4. #去哪儿网链接
5. urls = 'http://piao.qunar.com/ticket/list.htm?keyword='+place+'®ion=&from=mpl_search_suggest&page='
6. i = 1
7. sightlist = []
8. #遍历页面
9. while i:
10. url=urls+str(i)
11. page = getPage(url)
12. selector = etree.HTML(page)
13. print ('正在爬取第' + str(i) + '页景点信息')
14. i+=1
15. informations = selector.xpath('//div[@class="result_list"]/div')
16. for inf in informations: #获取必要信息
17. sight_name = inf.xpath('./div/div/h3/a/text()')[0]
18. sight_level = inf.xpath('.//span[@class="level"]/text()')
19. if len(sight_level):
20. sight_level = sight_level[0].replace('景区','')
21. else:
22. sight_level = 0
23. sight_area = inf.xpath('.//span[@class="area"]/a/text()')[0]
24. sight_hot = inf.xpath('.//span[@class="product_star_level"]//span/text()')[0].replace('热度 ','')
25. sight_add = inf.xpath('.//p[@class="address color999"]/span/text()')[0]
26. sight_add = re.sub('地址:|(.*?)|.∗?.∗?|,.*?$|\/.*?$','',str(sight_add))
27. sight_slogen = inf.xpath('.//div[@class="intro color999"]/text()')[0]
28. sight_price = inf.xpath('.//span[@class="sight_item_price"]/em/text()')
29. if len(sight_price):
30. sight_price = sight_price[0]
31. else:
32. i = 0
33. break
34. sight_soldnum = inf.xpath('.//span[@class="hot_num"]/text()')[0]
35. sight_url = inf.xpath('.//h3/a[@class="name"]/@href')[0]
36. sightlist.append([sight_name,sight_level,sight_area,float(sight_price),int(sight_soldnum),float(sight_hot),sight_add.replace('地址:',''),sight_slogen,sight_url])
37. time.sleep(3)
return sightlist,place
(运行效果图)
③至此,地点已经爬出来了。那么,既然要绘制热力图,那必不可少的就是经纬度了,在这里,我们可以调用百度地图API来写出结果。
1. #通过百度地图API查询景点的经纬度
2. def getBaiduGeo(sightlist,name):
3. ak = '你的密钥'
4. #定义头文件
5. headers = {
6. 'User-Agent' :'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Safari/537.36'
7. }
8. list = sightlist
9. bjsonlist = []
10. ejsonlist1 = []
11. ejsonlist2 = []
12. num = 1
13. for l in list:
14. try:
15. address = l[0]
16. url = 'http://api.map.baidu.com/geocoder/v2/?address=' + address + '&output=json&ak=' + ak
17. json_data = requests.get(url = url).json()
18. print(json_data)
19. json_geo = json_data['result']['location']
20. except:
21. continue
22. json_geo['count'] = l[4]
23. bjsonlist.append(json_geo)
24. ejson1 = {l[0] : [json_geo['lng'],json_geo['lat']]}
25. ejsonlist1 = dict(ejsonlist1,**ejson1)
26. ejson2 = {'name' : l[0],'value' : l[4]/100}
27. ejsonlist2.append(ejson2)
28. print ('正在生成第' + str(num) + '个景点的经纬度')
29. num +=1
30. bjsonlist =json.dumps(bjsonlist)
31. ejsonlist1 = json.dumps(ejsonlist1,ensure_ascii=False)
32. ejsonlist2 = json.dumps(ejsonlist2,ensure_ascii=False)
33. with open('./points.json',"w") as f:
34. f.write(bjsonlist)
35. with open('./geoCoordMap.json',"w") as f:
36. f.write(ejsonlist1)
37. with open('./data.json',"w") as f:
38. f.write(ejsonlist2)
④输出的json数据大概长这样:经纬度和热度
⑤这样就得到了各景点的数据了,接下来就是绘制热力图了,选了个简单粗暴的办法,依然用百度地图API
1. <!DOCTYPE html>
2. <html>
3. <head>
4. <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
5. <meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
6. <script type="text/javascript" src="http://api.map.baidu.com/api?v=2.0&ak=你的密钥"></script>
7. <script type="text/javascript" src="http://api.map.baidu.com/library/Heatmap/2.0/src/Heatmap_min.js"></script>
8. <title>热力图功能示例</title>
9. <style type="text/css">
10. ul,li{list-style: none;margin:0;padding:0;float:left;}
11. html{height:100%}
12. body{height:100%;margin:0px;padding:0px;font-family:"微软雅黑";}
13. #container{height:800px;width:100%;}
14. #r-result{width:100%;}
15. </style>
16.</head>
17.<body>
18. <div id="container"></div>
19. <div id="r-result">
20. <input type="button" onclick="openHeatmap();" value="显示热力图"/><input type="button" onclick="closeHeatmap();" value="关闭热力图"/>
21. </div>
22.</body>
23.</html>
24.<script type="text/javascript">
25. var map = new BMap.Map("container"); // 创建地图实例
26.
27. var point = new BMap.Point(113.018261, 28.221984);
28. map.centerAndZoom(point, 12); // 初始化地图,设置中心点坐标和地图级别
29. map.enableScrollWheelZoom(); // 允许滚轮缩放
30.
31. var points =[这里填景点的json数据];
32.
33. if(!isSupportCanvas()){
34. alert('热力图目前只支持有canvas支持的浏览器,您所使用的浏览器不能使用热力图功能~')
35. }
36. //详细的参数,可以查看heatmap.js的文档 https://github.com/pa7/heatmap.js/blob/master/README.md
37. //参数说明如下:
38. /* visible 热力图是否显示,默认为true
39. * opacity 热力的透明度,1-100
40. * radius 势力图的每个点的半径大小
41. * gradient {JSON} 热力图的渐变区间 . gradient如下所示
42. * {
43. .2:'rgb(0, 255, 255)',
44. .5:'rgb(0, 110, 255)',
45. .8:'rgb(100, 0, 255)'
46. }
47. 其中 key 表示插值的位置, 0~1.
48. value 为颜色值.
49. */
50. heatmapOverlay = new BMapLib.HeatmapOverlay({"radius":20});
51. map.addOverlay(heatmapOverlay);
52. heatmapOverlay.setDataSet({data:points,max:100});
53. //是否显示热力图
54. function openHeatmap(){
55. heatmapOverlay.show();
56. }
57. function closeHeatmap(){
58. heatmapOverlay.hide();
59. }
60. closeHeatmap();
61. function setGradient(){
62. /*格式如下所示:
63. {
64. 0:'rgb(102, 255, 0)',
65. .5:'rgb(255, 170, 0)',
66. 1:'rgb(255, 0, 0)'
67. }*/
68. var gradient = {};
69. var colors = document.querySelectorAll("input[type='color']");
70. colors = [].slice.call(colors,0);
71. colors.forEach(function(ele){
72. gradient[ele.getAttribute("data-key")] = ele.value;
73. });
74. heatmapOverlay.setOptions({"gradient":gradient});
75. }
76. //判断浏览区是否支持canvas
77. function isSupportCanvas(){
78. var elem = document.createElement('canvas');
79. return !!(elem.getContext && elem.getContext('2d'));
80. } </script>
⑥访问这个网页就得到了热力图,以下是效果图。
如图,我们可以看到五一广场、橘子洲、世界之窗等这几个位置热力突出,说明人流量非常大。妹坨可以去这些地方“卖冰棒”啦!
满锅赶紧把这一消息告诉了妹坨
妹坨惊呆了,“你怎么可以这么厉害!”
她愣了
这才想起,满锅是电子商务工作室的
所以才有这么高的水平
电子商务工作室是湖南财政经济学院信息技术与管理学院设立的学生组织,为学生提供超多的学习机会及工作经验。感受最前沿的互联网技术,做最优秀的新媒体运营。欢迎报名电子商务工作室。
撰稿:王梓杭
编辑:余伟娴
审核:李博