美文网首页
爬虫简单分析十一热门旅游景点分布

爬虫简单分析十一热门旅游景点分布

作者: 一只膨胀的猪 | 来源:发表于2017-09-29 17:17 被阅读0次

先上两张图:

十一热门景点前10景点分布(mark点标注)

样本数据间的方差貌似有点大。。点与点之间的差别确实有点大。。
本不是搞统计学或者数据挖掘的,只是一个不称职的小前端,所以请忽略下文中不严谨的统计方法:)


1500个热门景点的分布图(有的点确实很小..)

前几天就在简书上看到一篇关于十一黄金周旅游热点分布的爬虫+数据可视化的文章,一时兴趣,觉得学了一段时间爬虫了自己也可以做,所以就花了点时间做了这个项目。爬虫用的是python+scrapy框架,数据库存储使用的mongodb,数据可视化用的是js+echarts。

首先,我们需要获取数据,选取某哪儿旅游网站作为爬取对象,经过一顿分析后开始动手写爬虫代码,说实话这个网站的页面结构比较规整,爬起来也比较方便顺手。。分析获取下一页链接的方法(好几种方法,也可以用selenium)。

        try:
            current_page = selector.xpath('//div[@id="pager-container"]/div/em/text()').extract()[0]
        except:
            return
        yield Request(url='http://piao.qunar.com/ticket/list.htm?keyword=%E4%B8%AD%E5%9B%BD&page='+str(int(current_page)+1),callback=self.parse)

选取的范围是爬虫热门景点的前100页,每个页面15个,共1500个景点。爬取的数据存放到本地的mongodb中。业务逻辑很简单,代码就没有必要再贴上来了。。。爬虫成果:


爬到数据后就是数据可视化的过程了。之前写过一两个echarts的页面,所以写起来也比较快了。首先可以先做一个热门景点的排行情况的图,参考的指标是网站中每个景点的售出票的数量,然后进行排序,将mongodb中的数据处理成“景点名-xxx,售票数量-xxx”这样的对应关系如下图:


之后就是对echarts的的配置项进行设置,筛选出前20名的热门景点。配置项series如下

series : [  
        {  
          "name":"热门景点排行榜",  
          "type":"bar",  
          "data":data.sort(function(a,b){
            return b.value-a.value
          }).slice(0,21).sort(function(a,b){
            return a.value-b.value
          }),  
          itemStyle : { normal: {label : {show: true,position: 'right',fontSize:18}}}
        }  
      ]  

先来一个条形图:


条形图比较直观的反映出排行的情况。
再从另外一个角度分析下,来看看每个省份的热门景点各有多少。简单的进行处理数据,然后用条形图展示:

可以看到排名前三的分别是四川、陕西和福建。
同样的处理方法,我们也可以对城市的热门景点进行统计,统计结果如下:

如果不考虑统计学原理,只为了好玩,还可以将这前10名的信息汇总成饼状图:

热门景点最多的省份-广东。

家乡河南热门景点有63个:)

热门景点最多的城市-北京。

郑州居然有16个热门景点。。没想到

再就是开头的那两张图了,之前公司做过类似姓氏迁徙的echarts图表(迁徙的图比单纯的地图分布的图表要复杂的多。。还要考虑数据量大影响渲染性能的问题,跟着公司大牛学了不少),配置项熟悉了后,进行配置。
地图除了每个点及点对应的值,还需要点对应的坐标,所以我们需要两组数据,一组是值得集合,一种是坐标的集合。值的集合:

    var data = [{
        "name": "稻城亚丁",
        "value": 17857
    }, {
        "name": "秦始皇陵博物院(兵马俑)",
        "value": 12571
    }, {
        "name": "鼓浪屿",
        "value": 4346
    }, {
        "name": "天门山国家森林公园",
        "value": 4145
    }, 

坐标的集合:

var geoCoordMap = {
        "稻城亚丁": [100.324691, 28.540034],
        "秦始皇陵博物院(兵马俑)": [109.266029, 34.386024],
        "鼓浪屿": [118.073486, 24.452261],
        "天门山国家森林公园": [110.482089, 29.072408],
        "颐和园": [116.276887, 39.999497],
        "故宫": [116.403347, 39.922148],
        "八达岭长城": [116.03293, 40.369733],
        "布达拉宫": [91.125491, 29.660076],
        "长隆野生动物世界": [113.335765, 23.0003],
        "黄山风景区": [118.193977, 30.097967],
        "长隆水上乐园": [113.331236, 23.005835],
          ...

地图的配置:

var convertData = function (data) {
        var res = [];
        for (var i = 0; i < data.length; i++) {
            var geoCoord = geoCoordMap[data[i].name];
            if (geoCoord) {
                res.push({
                    name: data[i].name,
                    value: geoCoord.concat(data[i].value)
                });
            }
        }
        return res;
    };

    option = {
        backgroundColor: '#404a59',
        title: {
            text: '十一黄金周热门旅游景点分布图',
            left: 'center',
            top:50,
            textStyle: {
                color: '#fff',
                fontSize:24
            }
        },
        tooltip: {
            trigger: 'item'
        },
        legend: {
            orient: 'vertical',
            y: 'bottom',
            x: 'right',
            data: ['pm2.5'],
            textStyle: {
                color: '#fff'
            }
        },
        geo: {
            map: 'china',
            label: {
                emphasis: {
                    show: false
                }
            },
            roam: true,
            itemStyle: {
                normal: {
                    areaColor: '#323c48',
                    borderColor: '#111'
                },
                emphasis: {
                    areaColor: '#2a333d'
                }
            }
        },
        tooltip:{
            trigger: 'item',
            formatter:function(params) {        //自定义tooltip
                console.log(params)
                var res = params.name+'<br/>';  
                var myseries = option.series;  
                for(var j=0;j<myseries[0].data.length;j++){  
                    if(myseries[0].data[j].name==params.name){  
                        res+='人气值' +' : '+myseries[0].data[j].value[2]+'</br>';  
                    }  
                }  
                return res;  
            }  
        },
        series: [{
                name: '热门景点',
                type: 'scatter',
                coordinateSystem: 'geo',
                data: convertData(data),
                symbolSize: function (val) {
                    return val[2] / 600;
                },
                label: {
                    normal: {
                        formatter: '{b}',
                        position: 'down',
                        show: false
                    },
                    emphasis: {
                        show: true
                    }
                },
                itemStyle: {
                    normal: {
                        color: '#ddb926'
                    }
                }
            },
            {
                name: 'Top 10',
                type: 'effectScatter',
                coordinateSystem: 'geo',
                data: convertData(data.sort(function (a, b) {
                    return b.value - a.value;
                }).slice(0, 11)),
                symbolSize: function (val) {
                    return val[2] / 600;
                },
                showEffectOn: 'render',
                rippleEffect: {
                    brushType: 'stroke'
                },
                hoverAnimation: true,
                label: {
                    normal: {
                        formatter: '{b}',
                        position: 'right',
                        show: false
                    }
                },
                itemStyle: {
                    normal: {
                        color: '#f4e925',
                        shadowBlur: 10,
                        shadowColor: '#333'
                    }
                },
                zlevel: 1
            }
        ]
    };

然后得到分布图:


以上就是所有可视化的展示内容。
后记:
断断续续学习python爬虫快两个月了,也写了几个爬虫的项目:91图片(大概2w多张)、腾讯公益《活着》活动的展示页(大概6k张图片)、天堂网(公司让爬的。。也不知道要这些数据有何用)大概2w多的有效用户信息、逼乎(水管太小,只爬了大概3w多的用户信息先作罢)、网易云音乐(爬接口爬了1w多用户)。现在简单的爬虫可以说是应付得来了,但是至于分布式队列,上redis那一套也只是试验了试验并没有深入的爬取,像redis上亿数据量去重优化(加布隆过滤器)这种技术点没有深入学习只是那别人的直接用(主要还是redis和内存优化这些之前都没接触过),究竟里边的坑有多深还不得而知,日后肯定要再继续学习。

相关文章

网友评论

      本文标题:爬虫简单分析十一热门旅游景点分布

      本文链接:https://www.haomeiwen.com/subject/gnniextx.html