零、废话
挖掘数据无论是对运营还是产品,都是一项相当重要的技能,尤其是在大数据时代,有效数据越多,决策的正确率越高。获取自己网站的各类数据当然是不成问题的,但是想要获取到竞品的各种数据往往是要付出较高的代价,有时就算是同一家公司兄弟部门的产品,一旦你开口想要运营数据时,你就会发现兄弟部门一点都不兄弟!!!所以,求人不如求己,能动手就别吵吵!
一般想要获取竞品比较详尽的数据是需要通过第三方平台的,但是这些平台的数据也是很有限的,例如最近上线的易观千帆,提供了大量移动应用的各种统计数据,但是这些数据一般只适合作为行业分析,对于产品和运营来说,想要作为一个功能或一个模块的决策依据是远远不够的。这时候,如果能自己写个简单的爬虫,不当显得高端大气,而且也是比较可靠的,自己动手,丰俭由人。
一、动手前的准备
要做什么?
假设我现在是一名视频应用行业的运营,日常工作之一获取竞品每天在推荐位都上了些什么视频,以及这些视频的播放量。这些数据可以用来分析行业的流行趋势以及自家产品和竞品在数据上的关系。今天我们拿优酷开刀,抓取他们首页的视频以及视频的播放量。
需要哪些知识?
- 爬虫脚本语言:python,只要知道些基本的语法。
- 爬虫框架:Scrapy
- 抓包工具:Charles或Fiddler或其他。。。
- 基本的命令行操作知识
- 基本的http知识
二、进入数据世界的大门
我们的目标是什么?获取竞品的数据!
竞品的数据存在哪里?服务器里?
怎样获取别人服务器里的数据?黑了它们的服务器!
you can you up...
各个公司与互联网之间会有许多相互连接的桥梁,其中最主要也是最容易获取的应该就是API了。获取api的方式多种多样,例如你想要抓取数据的网站或应用没有公开API,但是很巧的你认识他们的开发者,这时候坑蒙拐骗可能是一种简单有效的方式,然而更普遍的方法是使用抓包工具。下面我们就以Charles演示怎么 获取到优酷ipad客户端的api。
Charles的使用并没有什么好说的,在设备上设置好代理就可以抓到设备的所有http请求了,万幸优酷并没有使用https协议,虽然并没有太大的差别。使用Filter筛选出所有youku的请求.
对host和path进行简单的分析揣测,可以很容易的猜出host为api.mobile.youku.com的就是优酷主要内容的api的host了。然后我们选中这个疑似优酷首页的请求,右键点击这个请求,然后点击edit选项,就可以很清晰的看出这个api的构成了。
首先这是一个get请求,api地址是http://api.mobile.youku.com/layout/ipad/home/adv
,下面的这一块就是请求的参数了,参数名都是些很亲切的单词啊,有用户id和设备id之类的,这些具体代表什么并不重要,只要知道请求的时候把参数填正确就行了。最后两个参数s和t就比较麻烦了,t应该是时间戳,这个值在一定时间段内有效,s我还没猜出来具体是代表什么,应该是根据时间戳以及其他参数一起计算出来的一个字段,这两个值都是在一个时间段内有效的。接下来我们复制这个请求链接,粘贴到浏览器里,就可以看到那些美妙的数据啦!
这些看起来很乱的数据,它们是有格式的,也就是传说中的json格式。找个工具格式化一下,这些数据的结构就非常清晰了!
三、进入“大”数据时代
优酷首页的数据仔细看下应该就能看出来,这是首页每一个视频对应的基本信息,这些数据看起来量很大,然而并没有什么用,因为这些数据里面并没有包含视频对应的播放量等信息。于是我们很机智的在视频的详情页中看到了有播放量的显示,所以我们接下来就是要抓取视频详情页的数据。随便扫了一眼就看到了详情页的api,我怎么会这么聪明呢!!
分分钟找到了播放量,Mission Success!但是问题又来了,我们不可能一个个的抓取数据啊,这样还不如直接手动记录下手机上显示的数值呢!于是乎我们要召唤出今天的主角了,那就是爬虫!
不想解释什么是爬虫,自己百度吧。今天我们要使用一个相对成熟的爬虫框架——Scrapy
Scrapy的github地址
Scrapy的中文教程地址
Scrapy是一款基于python语言的爬虫框架,跨平台,功能强大,语言入门难度低。相对于没有基础的人来说是个还算不错的选择吧,顺利的完成中文教程中的这前三部分后,就可以愉快的抓取一些简单的数据啦
离开本文学习中。。。。。。
默默的写好了爬虫文件,对于这个例子,只需要一个简单的文件就行了,先上代码。PS:里面有部分参数做了修改,所以直接复制粘贴肯定是不能用的
###########引入必要的包
#用于设置文本格式,方便输出
import sys
reload(sys)
sys.setdefaultencoding('utf-8')
#scrapy爬虫和json格式以及Request必要的包
import scrapy
import json
from scrapy.http import Request
###########爬虫主要代码
class DmozSpider(scrapy.Spider):
#声明接口和各种参数的变量,方便修改和调用
home_api="http://api.mobile.youku.com/layout/ipad/home/adv"
global detail_api,ouid,idfa,vdid,brand,os,ver,deviceid,guid,network,pid,os_ver,btype,_t_,_s_
detail_api="http://api.mobile.youku.com/layout/ipad4_0/play/detail"
ouid ="8fa2748394da5b97f6636c064faaf3f61ef3442c2"
idfa="9C333152-19FE-4703-B026-BBBD17B4D0E7"
vdid="CF555DE3-3A07-429A-97FA-5D2431AD6005"
brand="apple"
os="ios"
ver="4%2E7%2E1"
deviceid ="0f777264fc6318a92b9e13c65db7cd3c"
guid="7066707222dc38af1621eaf94a6fe779"
network="WIFI"
pid="87c959fb273378eb"
os_ver="10%2E0%2E2"
btype="iPad5,3"
_s_="fec9043f65a06935a2327497d868aa67"
_t_="1475939554"
#教程例子中有。。。
name = "dmoz"
allowed_domains = ["youku.com"]
start_urls = [
# 拼凑优酷首页的请求地址
home_api+"?"+"ouid="+ouid+"&idfa="+idfa+"&vdid="
+vdid+"&brand="+brand+"&os="+os+"&ver="+ver
+"&deviceid="+deviceid+"&guid="+guid+"&network="
+network+"&pid="+pid+"&os_ver="+os_ver+"&btype="+btype+"&_s_="+_s_+"&_t_="+_t_
]
def parse(self, response):
# 请求首页地址成功是的返回操作,下面两个参数是详情页对应的_s_和_t_,首页和详情页的这两个参数值是不一样的,这两个参数也只有几分钟的有效时间
d_s_="3f9ecdaf156976e1c43022ac115e22c7"
d_t_="1475939594"
#将首页请求到的数据转换为json格式,方便后续操作
js = json.loads(response.body_as_unicode())
#从返回的数据中取出key为“results”对应的值
vsresult=js['results']
#对上面获取到的值进行循环遍历,获取到里面所有的视频信息
for results in vsresult:
try:
vds=results["videos"]
for vd in vds:
#获取到视频的id,然后拼凑成视频详情页的请求链接
tid=vd['tid']
detailurl=detail_api+"?"+"id="+tid+"&ouid="+ouid+"&idfa="+idfa+"&vdid="+vdid+"&brand="+brand+"&os="+os+"&ver="+ver+"&deviceid="+deviceid+"&guid="+guid+"&network="+network+"&pid="+pid+"&os_ver="+os_ver+"&btype="+btype+"&_s_="+d_s_+"&_t_="+d_t_
#请求视频详情页地址,请求的返回结果调用parse_detail函数
yield Request(detailurl, callback=self.parse_detail)
except Exception as e:
continue
#请求视频详情页成功时调用的函数
def parse_detail(self,response):
#将返回的数据转换为json格式,并取出相应的值
js = json.loads(response.body_as_unicode())
res=js["detail"]
title=res["title"]
total_vv=res["total_vv"]
ret=title+" download: "+total_vv+"\n"
#将获取到的值写入data.txt文件中
f=file("data.txt","a+")
f.write(ret)
f.close()
这就是取得的最终结果,是不是看上去很简单?好吧,确实有些复杂,然而这只是最最基本的应用了,掌握了方法之后,爬虫可以办到非常多很有意思的事情哦!