写爬虫之前,首先要明确爬取的数据。然后,思考从哪些地方可以获取这些数据。下面以一个实际案例来说明,怎么寻找一个好的爬虫策略。(代码仅供学习交流,切勿用作商业或其他有害行为)
1).方式一:直接爬取网站 目标网址:http://chanyouji.com/ 注意:这个网站会拦截IP,访问次数过多,IP会被封,所以,上节的IP代理就用到了。
a).打开网页,可以看到这是一个游记类的网站,里面有很多人分享的游记。那我们就爬这些游记。说不定以后有时间出去玩的时候可以用到。
b).点开其中一篇游记,可以看到链接地址形式是这样的 http://chanyouji.com/trips/352140,这个时候,我们可以思考一下,352140这个数字代表的含义,会不 会是这个游记在数据库的ID,如果是的话,换个数字会不会得到不一样的游记,那么我们试一下。访问 http://chanyouji.com/trips/352141,可以看到,的确得到了不 一样的游记。截图如下:
c).从网址上可以得出一个结论,我们可以通过枚举来请求到不同的数据。但是,这并不一定是可以按照上两节的方式来爬取。原因有很多。比如,有些数据是通过js渲染 的。对于有web开发基础的很好理解,但是对于没有做过web开发的同学解释一下。假设,我们要买一个房子,房子有很多种,我们分成两类,一类是毛坯房(就是没有装修 的),一类是装修好的。对于毛坯房,我们要买家具,装修什么的,对于装修好的我们可以直接用。类比到这个例子中,http://chanyouji.com/trips/*****这个请求就买 一个房子,毛坯房就是说返回的是这个网站的壳子,需要另外在JS里面重新请求数据,填充到壳子里面。装修好的就是,数据什么的都填好了,一起给你。
d).那么我们该如何判断,这两类的结果呢。很简单。以火狐浏览器为例,F12打开调试窗口,找到网络->点击相应的请求,可以看到如下界面:
这个请求的所有的数据都会显示在这个里面,然后点开响应,会看到请求来的源代码(这个也是我们用爬虫发请求的结果),如图所示
很庆幸,我们获取到的是精装房,可以直接利于上两节的知识来解析这个代码(这里就不赘述了)
e).如果是js渲染的怎么办呢?我没在这个网站上找到用js渲染的(这个网站的数据还是比较好爬,除了拦截IP之外,没有多少难度),所以换个目标来解释。
2) 方式二:分析请求 目标网址:http://music.163.com/#/user/home?id=48353(丁磊的网易云音乐个人主页)开始分析方法和上一步一样,页面截图如下:
a).我们发现,http://music.163.com/user/home?id=48353 这个请求返回的值是不是少点什么,对的,就是少了歌单(如果多分析几个用户的页面,你会发现,年龄 也是缺的)
b).我们继续寻找那个歌单的数据在哪里?
可以看到,http://music.163.com/weapi/user/playlist?csrf_token= 这个请求就是返回的歌单,我们只需要请求这个接口的时候,带上该有的参数,就能得到这个数据。返回的数据是json格式,可以拿过来直接用了,不用beautifulsoup解析。另外说一句,这个接口的参数是加密的,如下图,网上有破解的,但是不推荐破解,因为只要他们随便改下密钥或者加密方式,又要花很大时间来破解。对于这个接口,我们一般参与,分析js(网易云音乐的js也是混淆过的)或者调用浏览器来访问(这个效率比较低,但是个人来讲够用了)。
3)方式三:另辟蹊径——利用目标网址的APP。这里仍以 蝉游记 为例。APP的接口返回值一般都是JSON,比较好解析,除了网易云音乐(丁磊就该好好养猪)。核心就是拦截APP的请求。
a).在电脑上安装安卓模拟器(我用的是bluestacks,这个安装好像有点麻烦)
b).在模拟器中安装目标APP--蝉游记(除了这个方法之外,还可以用电脑开个热点,用手机连接这个热点,同样可以拦截)
c).安装http analyzer其他的也行,就是拦截http请求用的),打开httpanalyzer
d).使用目标APP,这个时候就可以拦截到想要的请求,如图:
e).请求就是这样的,这里要注意,https和http的区别。遇到https的请求,我们先试下用http替换。很庆幸,这个网站可以这样做,如果不可以的话,比较麻烦,还要导 入证书(暂且不讲)。我们把http://chanyouji.com/api/trips/352140.json (为了和方式一同步,把id改成了352140)发到浏览器中请求,结果如下(说明请求的时候不 需要加任何参数)
f).这些数据比较多,很难看。怎么看好看一点呢,就是把它转化成标准的json数据,我一般用这个工具http://www.bejson.com/jsonviewernew/
把数据复制过去格式化一下就行了。如下图所示:
g).顺便说一句,python有json解析模块,可以用。
下面附上蝉游记的爬虫源码(仅供学习交流!仅供学习交流!仅供学习交流!)
import urllib import json import socket socket.setdefaulttimeout(10) proxys = [] proxys.append({"http":"http://124.251.62.246:80"}) proxys.append({"http":"http://117.78.34.32:80"}) proxys.append({"http":"http://59.108.61.132:808"}) for id in range(0,5,1): try: url = "http://chanyouji.com/api/trips/"+`(352140+id)`+".json" res = urllib.urlopen(url,proxies=proxys[id%3]).read() res_json = json.loads(res) print res_json['name'] except Exception,e: print e continue
运行结果:
代码说明:
a).枚举可以用循环
b). res_json = json.loads(res) 就是把结果转化成json,特别注意,这个res必须要有和json格式一样(json相关资料,可自行查阅)。
c).proxys.append()就是往数组中添加元素
d).id%3 就是id处于3取其余数,也就是说 id%3大于等于0,小于等于2。因为代理只有三个,数组是从零开始。
到此,简单的爬虫策略就讲完了。
备注:
a).所有内容仅供学习交流使用
b).如有错误,多多指教
c).转载请注明出处