通常来说对咱们而言,须要抓取的是某个网站或者某个应用的内容,提取有用的价值,内容通常分为两部分,非结构化的文本,或结构化的文本。javascript
HTML文本基本上是传统爬虫过程当中最多见的,也就是大多数时候会遇到的状况,例如抓取一个网页,获得的是HTML,而后须要解析一些常见的元素,提取一些关键的信息。HTML其实理应属于结构化的文本组织,可是又由于通常咱们须要的关键信息并不是直接能够获得,须要进行对HTML的解析查找,甚至一些字符串操做才能获得,因此仍是归类于非结构化的数据处理中。css
常看法析方式以下:html
如今的网页样式比较多,因此通常的网页都会有一些CSS的定位,例如class,id等等,或者咱们根据常见的节点路径进行定位,例如腾讯首页的财经部分。java
这里id就为finance,咱们用css选择器,就是"#finance"就获得了财经这一块区域的html,同理,能够根据特定的css选择器能够获取其余的内容。正则表达式
XPATH是一种页面元素的路径选择方法,利用Chrome能够快速获得,如:编程
copy XPATH 就能获得——//*[@id="finance"]跨域
正则表达式,用标准正则解析,通常会把HTML当作普通文本,用指定格式匹配当相关文本,适合小片断文本,或者某一串字符,或者HTML包含javascript的代码,没法用CSS选择器或者XPATH。浏览器
同正则表达式,更为偷懒的方法,不建议使用。服务器
如今的代理种类比较多,目前在用这个cookie
http://http.zhimaruanjian.com/
例如一篇文章,或者一句话,咱们的初衷是提取有效信息,因此若是是滞后处理,能够直接存储,若是是须要实时提取有用信息,常见的处理方式以下:
根据抓取的网站类型,使用不一样词库,进行基本的分词,而后变成词频统计,相似于向量的表示,词为方向,词频为长度。
天然语言处理,进行语义分析,用结果表示,例如正负面等。
结构化的数据是最好处理,通常都是相似JSON格式的字符串,直接解析JSON数据就能够了,提取JSON的关键字段便可。
过去咱们常须要获取的内容主要来源于网页,通常来说,咱们决定进行抓取的时候,都是网页上可看到的内容,可是随着这几年移动互联网的发展,咱们也发现愈来愈多的内容会来源于移动App,因此爬虫就不止局限于必定要抓取解析网页,还有就是模拟移动app的网络请求进行抓取,因此这一部分我会分两部分进行说明。
网页内容通常就是指咱们最终在网页上看到的内容,可是这个过程其实并非网页的代码里面直接包含内容这么简单,因此对于不少新人而言,会遇到不少问题,好比:
明明在页面用Chrome或者Firefox进行审查元素时能看到某个HTML标签下包含内容,可是抓取的时候为空。
不少内容必定要在页面上点击某个按钮或者进行某个交互操做才能显示出来。
因此对于不少新人的作法是用某个语言别人模拟浏览器操做的库,其实就是调用本地浏览器或者是包含了一些执行JavaScript的引擎来进行模拟操做抓取数据,可是这种作法显然对于想要大量抓取数据的状况下是效率很是低下,而且对于技术人员自己而言也至关于在用一个盒子,那么对于这些内容究竟是怎么显示在网页上的呢?主要分为如下几种状况:
这种状况是最容易解决的,通常来说基本上是静态网页已经写死的内容,或者动态网页,采用模板渲染,浏览器获取到HTML的时候已是包含全部的关键信息,因此直接在网页上看到的内容均可以经过特定的HTML标签获得。
这种状况是因为虽然网页显示时,内容在HTML标签里面,可是实际上是因为执行js代码加到标签里面的,因此这个时候内容在js代码里面的,而js的执行是在浏览器端的操做,因此用程序去请求网页地址的时候,获得的response是网页代码和js的代码,因此本身在浏览器端能看到内容,解析时因为js未执行,确定找到指定HTML标签下内容确定为空,这个时候的处理办法,通常来说主要是要找到包含内容的js代码串,而后经过正则表达式得到相应的内容,而不是解析HTML标签。
这种状况是如今很常见的,尤为是在内容以分页形式显示在网页上,而且页面无刷新,或者是对网页进行某个交互操做后,获得内容。那咱们该如何分析这些请求呢?这里我以Chrome的操做为例,进行说明:
因此当咱们开始刷新页面的时候就要开始跟踪全部的请求,观察数据究竟是在哪一步加载进来的。而后当咱们找到核心的异步请求的时候,就只用抓取这个异步请求就能够了,若是原始网页没有任何有用信息,也不必去抓取原始网页了。
由于如今移动应用愈来愈多,不少有用信息都在App里面,另外解析非结构化文本和结构文本对比而言,结构化文本会简单多了,不一样去找内容,去过多分析解析,全部既有网站又有App的话,推荐抓取App,大多数状况下基本上只是一些JSON数据的API了。
那么App的数据该如何抓取呢?通用的方法就是抓包,基本的作法就是电脑安装抓包软件,配置好端口,而后记下ip,手机端和电脑在同一个局域网里面,而后在手机的网络链接里面设置好代理,这个时候打开App进行一些操做,若是有网络数据请求,则都会被抓包软件记下,就如上Chrome分析网络请求同样,你能够看到全部的请求状况,能够模拟请求操做。这里Mac上我推荐软件Charles,Windows推荐Fiddler2。
具体如何使用,以后我再作详述,可能会涉及到HTTPS证书的问题。
刚刚一直在宽泛的提到一些咱们须要找到请求,进行请求,对于请求只是一笔带过,但请求是很重要的一部分,包括如何绕过限制,如何发送正确地数据,都须要对的请求,这里就要详细的展开说下请求,以及如何模拟请求。
咱们常说爬虫其实就是一堆的HTTP请求,找到待爬取的连接,无论是网页连接仍是App抓包获得的API连接,而后发送一个请求包,获得一个返回包(也有HTTP长链接,或者Streaming的状况,这里不考虑),因此核心的几个要素就是:
在用Chrome进行网络请求捕获或者用抓包工具分析请求时,最重要的是弄清楚URL,请求方法,而后headers里面的字段,大多数出问题就出在headers里面,最常限制的几个字段就是User-Agent, Referer, Cookie 另外Base Auth也是在headers里面加了Autheration的字段。
请求内容也就是post时须要发送的数据,通常都是将Key-Value进行urlencode。返回包headers大多数会被人忽视,可能只获得内容就能够了,可是其实不少时候,不少人会发现明明url,请求方法还有请求包的内容都对了,为何没有返回内容,或者发现请求被限制,其实这里大概有两个缘由:
一个是返回包的内容是空的,可是在返回包的headers的字段里面有个Location,这个Location字段就是告诉浏览器重定向,因此有时候代码没有自动跟踪,天然就没有内容了;
另一个就是不少人会头疼的Cookie问题,简单说就是浏览器为何知道你的请求合法的,例如已登陆等等,其实就是可能你以前某个请求的返回包的headers里面有个字段叫Set-Cookie,Cookie存在本地,一旦设置后,除非过时,通常都会自动加在请求字段上,因此Set-Cookie里面的内容就会告诉浏览器存多久,存的是什么内容,在哪一个路径下有用,Cookie都是在指定域下,通常都不跨域,域就是你请求的连接host。
因此分析请求时,必定要注意前四个,在模拟时保持一致,同时观察第五个返回时是否是有限制或者有重定向。
上述都是讲的都是一些的基础的知识,如今我就列一些比较常见的限制方式,如何突破这些限制抓取数据。
频繁抓取,须要大量更换ip,能够在http://http.zhimaruanjian.com/提取;
通常会有用户受权的限制,会在headers的Autheration字段里要求加入;
一般是在访问连接时,必需要带上Referer字段,服务器会进行验证,例如抓取京东的评论;
会要求真是的设备,若是不加会用编程语言包里自有User-Agent,能够被辨别出来;
通常在用户登陆或者某些操做后,服务端会在返回包中包含Cookie信息要求浏览器设置Cookie,没有Cookie会很容易被辨别出来是伪造请求;
也有本地经过JS,根据服务端返回的某个信息进行处理生成的加密信息,设置在Cookie里面;
请求headers里面带了gzip,返回有时候会是gzip压缩,须要解压;
通常都是在请求的数据包内容里面会包含一些被javascript进行加密限制的信息,例如新浪微博会进行SHA1和RSA加密,以前是两次SHA1加密,而后发送的密码和用户名都会被加密;
由于http的headers能够自定义地段,因此第三方可能会加入了一些自定义的字段名称或者字段值,这也是须要注意的。
真实的请求过程当中,其实不止上面某一种限制,多是几种限制组合在一次,好比若是是相似RSA加密的话,可能先请求服务器获得Cookie,而后再带着Cookie去请求服务器拿到公钥,而后再用js进行加密,再发送数据到服务器。因此弄清楚这其中的原理,而且耐心分析很重要。
首先大的地方,加入咱们想抓取某个数据源,咱们要知道大概有哪些路径能够获取到数据源,基本上无外乎三种:
原则是能抓移动App的,最好抓移动App,若是有针对移动设备优化的网站,就抓针对移动设备优化的网站,最后考虑PC网站。由于移动App基本都是API很简单,而移动设备访问优化的网站通常来说都是结构简单清晰的HTML,而PC网站天然是最复杂的了;
针对PC端网站和移动网站的作法同样,分析思路能够一块儿讲,移动App单独分析。
首先是网站类的,使用的工具就是Chrome,建议用Chrome的隐身模式,分析时不用频繁清楚cookie,直接关闭窗口就能够了。
具体操做步骤以下:
分析异步请求,按照网络列表,略过资源文件,而后点击各个请求,观察是否在返回时包含想要的内容,有几个方法:
针对分析对请求的限制,思路是逆序方法。
而后是App类的,使用的工具是Charles,手机和电脑在一个局域网内,先用Charles配置好端口,而后手机设置代理,ip为电脑的ip,端口为设置的端口,而后若是手机上请求网络内容时,Charles会显示相应地请求,那么就ok了,分析的大致逻辑基本一致,限制会相对少不少,可是也有几种状况须要注意:
通常来说在抓取大量数据,例如全网抓取京东的评论,微博全部人的信息,微博信息,关注关系等等,这种上十亿到百亿次设置千亿次的请求必须考虑效率,否者一天只有86400秒,那么一秒钟要抓100次,一天也才864w次请求,也须要100多天才能到达十亿级别的请求量。想要抓取效率高必不可免的就是ip了,http://http.zhimaruanjian.com/。
涉及到大规模的抓取,必定要有良好的爬虫设计,通常不少开源的爬虫框架也都是有限制的,由于中间涉及到不少其余的问题,例如数据结构,重复抓取过滤的问题,固然最重要的是要把带宽利用满,因此分布式抓取很重要,接下来我会有一篇专门讲分布式的爬虫设计,分布式最重要的就是中间消息通讯,若是想要抓的越多越快,那么对中间的消息系统的吞吐量要求也越高。
可是对于一些不太大规模的抓取就没要用分布式的一套,比较消耗时间,基本只要保证单机器的带宽可以利用满就没问题,因此作好并发就能够,另外对于数据结构也要有必定的控制,不少人写程序,内存越写越大,抓取愈来愈慢,可能存在的缘由就包括,一个是用了内存存一些数据没有进行释放,第二个可能有一些hashset的判断,最后判断的效率愈来愈低,好比用bloomfilter替换就会优化不少。