摩拜单车非官方大数据分析

趁着过年的清闲时光,我抓取了摩拜单车的数据并进行了大数据分析。以下数据分析自1月19日整日的数据,范围成都绕城区域以及至华阳附近(天府新区)内。成都的摩拜单车的整体情况如下:

标准车型和Lite车型数量相当

摩拜单车在成都大约已经有6万多辆车,两种类型的车分别占有率为55%和44%,可见更为好骑的Lite版本的占有率在提高。(1为标准车,2为Lite车型)

单车类型

三成左右的车没有移动过

数据分析显示,有三成的单车并没有任何移动,这说明这些单车有可能被放在不可获取或者偏僻地方。市民的素质还有待提高啊。

出行距离以3公里以下为主

数据分析显示3公里以下的出行距离占据了87.2%,这也十分符合共享单车的定位。100米以下的距离也占据了大量的数据,但认为100米以下的数据为GPS的波动,所以予以排除。

出行距离分布

单车骑行次数以5次以下居多

单车的使用频率越高共享的效果越好。从摩拜单车的数据看,在流动的单车中,5次以下占据了60%左右的出行。但1次、2次的也占据了30%左右的份额,说明摩拜单车的利用率也不是很高。

单车骑行次数

单车骑行次数

从单车看城市发展

从摩拜单车的热图分布来看,成都已经逐步呈现“双核”发展的态势,城市的新中心天府新区正在聚集更多的人和机会。

双核发展

原来的老城区占有大量的单车,在老城区,热图显示在东城区占有更多的单车,可能和这里的商业(春熙路、太古里、万达)及人口密集的小区有直接的联系。

老城区

而在成都的南部天府新区越来越多也茁壮的发展起来,商业区域和住宅区域区分明显。在晚上,大量的单车聚集在华阳、世纪城、中和,而在上班时间,则大量聚集在软件园附近。

软件园夜间

软件园白天

在线网站

如果你对数据感兴趣,我已经创建了一个网站供大家使用,请用电脑访问:http://www.april1985.com/mobike/
(为节省开支,后端服务器已经关闭)

Why docker use up all your disk space?

I noticed that the docker containers are using more and more disk spaces on host machine. By looking at the disk usage inside docker container, you will not see any disk usage increase. But the aufs file system is increasing.

I found out that there are two days we can use to clean up the space:

  1. Restart docker service
  2. Delete the docker container and add it back again.

But these ways need stop your service and we still don’t know the root cause.

After a deep search, I finally found that the log file is eating my disk space and docker will not clean or limit the file size by default. My docker container has plenty of logs output to console, so the log file will keep increasing. If I restarted the docker service or recreate docker container, the log is clean up. Fortunately, docker provide us a option to limit the log size:

--log-opt max-size=[0-9]+[kmg]
--log-opt max-file=[0-9]+
--log-opt labels=label1,label2
--log-opt env=env1,env2

I recreated my container using max-size option to limit the log size to 100M when running docker.

docker run .... --log-opt max-size=100M

By doing this, the problem is solved. You can find out more options for log on that page to manage your log.

再看API设计——从黑客的角度

互联网的高速发展以及多终端设备的广泛使用使得前后端分离架构变成了必须,越来越多的网络应用暴露出API以便于前端的使用,RESTFul API的设计成为了业界主流的设计范式。在持续的业务增长以及后端技术的革新中,微服务架构(Microservice)崭露头角,解决了单体应用(Monolithic Application)的诸多问题而越来越流行。现在,在客户端与服务、服务与服务之间,有更多的数据通过常用的json等结构化的方式进行交互。这些交互过程在单体应用中对外并不可见,但在微服务架构下对于却变得透明,黑客可以通过窥探及猜测系统内部的结构,会比以前更容易攻击系统。在这篇文章中,我将以一个数据黑客的角度,展示如何利用API来大规模的获取所要的信息。

数据黑客

数据黑客没有一个准确的定义,在我看来这帮人对于数据具有敏锐的嗅觉;他们尝试得到一切能够获得的数据并进行数据分析;他们尝试在数据的云海中找出规律以便预测未来。在程序员拯救世界的今天,数据黑客则掌握了世界的未来。

在若干年前,前后端分离的架构还尚未普及,很多数据的呈现方式都是直接在页面中打印出来,为了解析数据,数据黑客们使用XPATH去解析数据,将数据装入数据库进行分析,甚至从中赚钱。如今,我们有着大量的API供使用,数据变得唾手可得。我们不用再去繁琐的解析易变的HTML,只需要访问一个URL即可获得我们需要的数据。

10天内获得自由职业网站8百万项目数据

我对自由职业充满了好奇,想试一下自由职业是怎么接到活的。在Freelancer网站上,几乎每分钟都有新的项目发布,一般一分钟之内就有好几个投标信息(bid)。每个投标信息包含了投标的内容、价格以及完成时间,然后雇主根据这些信息来筛选谁可能接这个项目。一般来讲会在交谈之后,明确所有的事宜后,再将项目分配给自由职业者。

作为自由职业者,我们可以看到其他人投标的价格以及别人的信誉度、别人做过的项目等信息,但不能看到具体的投标内容。作为雇主,价格、自由职业者的信誉度、是否通过一些测试可能都是影响雇主是否第一轮筛选进行交谈。那么,通过数据分析,能否回答以下几个问题以便帮助我们正确的投标:

  • 针对投标信息,雇主对自由职业者的信誉度和价格,哪个看得更重?
  • 针对澳洲的雇主,我如何能够增加我被选中的几率,是通过降低价格还是提升自己的质量?

为了回答这些问题,我需要尽快的将网站上所有可能拿到的信息都拿下来进行分析。

网站及API分析

打开一个项目页面(注:你需要翻墙),你会看到页面如图所示:

image

简单的看一下HTML后,发现网站将所有的信息都内嵌到HTML中的一个script中,在浏览器执行完成后会得到project变量。这个变量包含了项目的所有信息,所以理论上讲,我们拿到一个HTML然后解析Javascript,是可以得到我们需要的数据的。

image

但这种方式也存在一些问题,一来是解析HTML非常费事,二来是执行Javascript也比较繁琐。并且没有一个办法能够遍历所有的项目,可行性并不大。

通常来讲,我不会去解析主网站,因为其防范一般比较严。但很多网站的马奇诺防线在移动端就失效了,Freelancer也不例外。

打开移动端的网页。简单看一下可以知道它是基于AngularJS写的网站。

image

通过分析API的请求,可以很快的看到API的样子:

image

我们来分析一下这个URL,红色部分代表了这个项目的简写名字,将其改为其他的项目名称以后能够得到对应的信息。

image

理论上我只要得到所有项目的简写名字,再用这个地址就可以获得所有的信息了。但且慢,我注意到了投标信息的API:

image

红色部分用的是一串数字,如果你了解RESTFul API,则很容易知道这个bids的信息是属于9844976项目的。将之前的projects后面的名字变为数字,果然返回ID为9844976的项目的信息,和用简写名字同样的效果。这样的话我就确定了网站每个项目的ID是可以直接访问的,从0开始遍历这个ID即可得到所有网站的信息。

image

阻力:API访问速度限制

当爬到1000个左右的时候,网站就报告API Rate Limit限制了,大概需要一个小时左右才能再次访问。作为一个大型的网站,API访问速度限制是很平常的事情。如果照这个速度访问,则爬完所有的信息需要将近一年。能不能更快呢?

通过匿名代理可以让访问的服务器无法识别出您的真实的IP地址,所以如果有大量的匿名代理,就可以满足爬虫的需求。但这个网站使用的是HTTPS,要找到大量稳定的HTTPS代理需要较高的代价,网络上常见的匿名代理网站提供的代理通常都不稳定。

image

那么,有没有一个更廉价的方式能够获得更多的IP地址呢?洋葱网络为我们提供可以非常好的途径来隐藏自己的真实身份,并能够得到大量稳定的IP,并且能够在达到API Rate Limit之前就更新IP地址,非常符合我们的要求。

image

为了让多线程并行,我在DigitalOcean的5美元的服务器上用Docker启动了10个Tor的客户端,这样每个客户端就拥有一个独立的IP,并且每10秒钟切换一次。脚本连续运行10天后,所有的数据全部到达本地。

从黑客的角度看

好的几点:

  • 该网站提供了移动端的API。
  • 有API的限速。

需要改进的有:

  • ID号可遍历:通过将ID变为UUID,可以解决资源被遍历的问题。但这个要视业务场景来定,如果业务上并没有需要保护数据,则简单的ID也是一种选择。
  • 加载的数据包含了很多额外的信息,造成一些信息泄露:在返回的数据中包含了大量的其他信息,黑客可以利用此信息得到页面上没有显示的信息。例如网站上对投标者对雇主的id、用户名等信息是不知道的,但API返回的数据中却有这些信息。这样黑客可以通过这些信息通过其他渠道联系上雇主。
  • 保护网站遭受匿名网络攻击:根据业务的不同,可以设置针对地域的IP限制。例如如果网站大部分针对澳洲客户,则澳洲客户的API使用量可以设置为1千/小时,而其他国家则设置为100个/小时,并且在适当时候显示验证码。

image

获得一年中6亿的机票数据

由于家庭的需要,我会在节假日往返成都和广州,而我想买到最便宜的机票。那么问题在于,我需要提前多少天才能买到足够便宜的机票呢?在我得到数据之前,我曾手工的看机票的数据,但很难发现规律,往往意识到涨价的时候,已经比最低值高出了很多。如果我能持续的抓取每天看到的30天之内的机票的数据,并用于一年后的数据分析,我是否能够找到一些规律呢?

为了完成这个任务,从2012年开始,我开始从各大机票售卖网站抓取机票信息。这里想举一个从某网站中获取机票的例子来看看我们能够从中学到一些什么。

我之前说过从主站入手往往很难攻破,所以直接打开移动的网站:

image

只需要看一下网络的请求就可以很方便的定位到获取机票的API以及返回值:

image

API分析

来我们看看API中包含了些什么:

data=%7B%22searchType%22%3A%……

这部分应该是存储的数据,很简单,我们通过decodeURI即可得到可见的信息:

image

后面一部分是固定的串,有API的key以及版本信息

useNative=true&ttid=201300@travel_h5_3.1.0&appKey=12574478

对于爬虫来讲,最麻烦的部分在于:

t=1426062775998&sign=3feb52aed67967a2c47aa7a2b9f2a417

image

这部分一直在变,并且若干秒后会失效。sign的计算和cookie中的mh5_tk有很大的关系,并且每次服务器要返回新的mh5_tk的token用于下一次请求。所以如果要生成这个url,必须要将他的计算规律搞清楚。对手前端的加密来讲,基本上如果了解js的开发,能够较快的找出来。首先搜索API中包含的字符串h5apiUpdate,很容易就定位到这里:

image

但这部分代码已经被压缩,无法打断点。Chrome提供了一个非常棒的代码格式化工具可以方便的将代码格式化为可读性很好的代码:

image
image

再在这里打上断点,所有的秘密都呈现在了眼前:

image
image

剩下的事情就是将这个写成脚本即可,请参考后记。

总结

从这个例子中我们学到了什么:

  • 可以用时间作为token来生成动态的url
  • 用sign去检查请求是否合法
  • 服务端可以用时间token来拒绝重发的请求
  • JS端的压缩可以较为容易的破解

后记

以上的代码我都分享在我的github账号。仅用于学习用途,请勿用于恶意攻击。

  • 关于爬Freelancer那的代码
  • 机票爬取的部分代码。由于网站已经升级,反爬措施变得比较难于琢磨,所以这段代码已经无法正常运行了,仅供参考。
  • 还有1分钟启动10个tor的代码

后来我发现Freelancer网站有一个隐藏的API接口文档,在这个文档中还有更多的信息可以参考。另外知乎上也有一些反爬虫的一些讨论,挺有趣,可以参考

API Design Best Practices -- From a hacker's view

两个星期前接到一个大坑,成都办公室需要人去参加客户的一个API的活动。和几个同事头脑风暴一番以后,发现客户已经有我们需要讲的议题了。那么我们搞点特别的吧,他们讲一些小正面的,我面来一些反面的。然后我就跳到了这个坑里。

从准备材料到最终讲只剩下一个多星期,花了两天多准备PPT,板式采用纯黑的主题,加上一些在flaticon上面找的图标,配起来自我感觉良好^_^。PPT在分享在这里,有兴趣的可以看。

关于Freelancer那的代码,阿里那一段段的代码,还有1分钟启动10个tor的代码

其实最近我发现Freelancer也是提供了API的文档的,只是这个网站的页面设计得很奇葩,找东西非常难找,在这里

乐山峨眉游(1)

峨眉山半价,走起!我从来都是不打不准备的仗,周五发红包给公司群,同事推荐了好多地方,花点钱真心不错。周六早上出发开车到乐山,中午就到乐山。下了高速赶紧定位到古市香跷脚牛肉,大众点评上有个订座的功能,开车半个小时到地方。

不得不说这个地方真的很火,在一条小巷子里面,有点不方便开车。在河边有免费停车的地方,,还算比较方便。下了车到店,发现这个不是一般的热闹,排号都排了很长。还好我是大众点评上先预定了的,马上安排座位,等了大概10分钟,还算幸福的啦。

牛杂牛肉粉蒸牛肉,依次点起!




房顶也有特色


外面卖的泡菜,要钱的哟,没点

吃好了一顿,也就100多块钱,非常的爽。牛杂我只吃牛肚,但牛肉吃了很多,粉蒸肉也吃完了,哈哈。

下午决定还是去乐山大佛一趟,去峨眉爬山时间肯定是不够了。车停在乐山大佛景区门口的景园停车场,20块钱的停车费,要了发票(这是我的特点,一定要发票),居然是那种餐饮样式的发票,盖章倒是正规的,还有刮奖。我的运气还算不错,一 5块,嘿嘿。

乐山大佛我倒是很小的时候去过,已经没有记忆了,只有照片。现在自己有了儿子,带着儿子重温我小时候的记忆。

乐山大佛

小朋友还是挺厉害的,自己爬山到顶上。下栈道就有点郁闷了,第一个转弯就堵了,半天不动。想想这还是个普通的周末,要是黄金周我看怎么办。走到一半才发现,台阶太陡,路越来越窄,只有够一个人,老婆提着儿子往下走,真的有点艰难。

乐山大佛
乐山大佛
下山栈道
乐山大佛

下山以后去峨眉山了,天色有点晚,还没订酒店。酒店的问题真是让我头痛,以前遭过两次,订了酒店没法取消,小孩生病没法去,白白的损失了一千多。这算是峨眉山旅游淡季了,应该没有那么挤。到了峨眉山脚下再找酒店,发现很多酒店都没了。也没关系,一家一家的打电话,最后找到了“凤缘酒店”还有房间。

老婆上去看了下房间,找了一间还不错的。讲价128一晚,携程上面订的的话要168的。停车还算不错了,虽然酒店门口只有三个位置,但后面一条巷子还有很大的停车场。老板一起带过去,免费停。房屋临街,但隔音做的不错不吵。房间有一点霉味,其他都还算好了。空调也不错,只是晚上有一些噪音,后来索性关了空调。

在老板娘那里订了灵秀温泉的票,网上买138,这里买125。后来才知道我们的价格也有点贵了,在外面有一个小超市门口有一个牌牌写的110-125,110块钱其实也能买到。晚上随便在外面找个了餐厅,结果找了个巨难吃的地方,详见我的点评

在这里吃过,价格比较贵不说,还做的相当难吃。
凤尾炒的全是烂七八糟的,酸菜粉丝汤的粉丝也是一股怪味,甚至酸菜里面还有一些清凉油的味道。最奇葩的苦笋,一股清凉油的味道,老板还是绝对是对的,也是醉了。。。,再也别去这里了

晚上去泡温泉,温泉距离酒店还是有一点距离,走路10分钟。大冬天的好冷啊。换了票进去,每个人要把鞋子脱了给你一个号。原来是因为后续你可以用这个号开关门,然后还可以买东西,最后出来的时候拿鞋子给钱。换衣服的地方还不是很冷,要主动去要浴袍,一个人只能拿一次干的。

温泉还是可以的,小孩的游泳圈没有带,有点郁闷。在外面的温泉玩了一下,赶紧到室内的温泉。室内的就要好很多了,泡了一个多小时,没有太大的感觉,回去赶紧再冲个热水澡。。。。

晚上睡了个好觉,准备第二天爬山。