爬虫课程(十三)|ajax分析法(雪球),通过获取api并破解api的反爬策略爬取数据
说明:本文是接着上一篇微博的ajax分析法进一步说明一种特殊情况。
我们在上一篇文章爬虫课程(十二)|ajax分析法(微博):通过获取api爬取新浪微博内容数据实战中通过分析获取ajax方式请求的api,通过这个api我们可以直接拿到返回的json数据。那么是不是分析出api就可以很轻易地获取到我们想要的数据呢?
一、分析获取雪球文章内容的api
首先我们依然打开chrome的开发者工具,点击network的标签,选择XHR。 如下图:
获取沪深下的文章信息
我们很轻易就拿到了获取文章信息的api,至此的操作过程基本和微博是一样的,是不是很简单?那么这次我们获取到的api是不是和微博一样可以直接获取到数据呢?
我们复制出这个api
https://xueqiu.com/v4/statuses/public_timeline_by_category.json?since_id=-1&max_id=-1&count=10&category=105
然后粘贴到浏览器的地址栏中,访问看看效果,为了防止之前的cookie的污染,我们打开一个chrome的隐身窗口。
打开chrome的隐身窗口
我们发现雪球的工程师对这个api竟然也做了反爬策略。
api的反爬
遇到这种情况,先不要慌,事在人为。我们开始进行反反爬。
二、破解api的反爬策略
一般来说,这种限制来自于三种常见的情况: 1.cookie;2.referer;3.url中的参数;
image.png
我们一般先测试2和3的情况,测试方法就是参照我们在浏览器中能正常访问到时的请求,删掉我们可能觉得不重要的参数,逐步测试。这里的测试方法就是我们上学时最熟悉的控制变量法——我们首先需要重现能够成功获取数据的情况,然后在一个一个变量进行调整,最终将无关的参数全部去除,并找到最核心的参数。当然这里我们还需要使用一个模拟提交请求的工具,我常用的是jmeter,当然也可以使用同类型的比如chrome的插件Advanced REST Client。 我们把cookie,referer和url完整的复制到请求中去,点击访问可以拿到数据。然后删除referer以及url中不相关的参数,重新点击访问依然可以拿到数据。我们推断他们的工程师的反爬技巧放在cookie上,而通过cookie做反爬又要分为三种情况: 1.没有变量,只要有就行;2.有变量,值是从http response返回的cookie设置;3.有变量,值是从js对cookie的设置。 使用1和2的情况较多,也相对比较简单,使用3的就比较麻烦啦。我们先来判断下他们是通过哪种方式。 我们先把请求api需要的cookie值复制出来:
aliyungf_tc=AQAAAEpsQUTQdggAKJVDZdqG9bOTHHjK;
xq_a_token=a8d434ddd975f5752965fa782596bd0b5b008376;
xq_a_token.sig=ke78qTMMk1J4blZPe-jY53Uy9Ec;
xq_r_token=437547d929e3cc54630bfd58136879694e1ae4a9;
xq_r_token.sig=iYuNwCitZuVpyfkOu6_LLtaQn6E;
u=291511526203608;
device_id=a4d5e9838df630d4ed110e85576d0482;
Hm_lvt_1db88642e346389874251b5a1eded6e3=1511526204,1511526232,1511527428,1511527463;
Hm_lpvt_1db88642e346389874251b5a1eded6e3=1511528364
我们首先依然要把cookie中不相关的参数,特别是一些统计代码的cookie删除掉,他们通常很长,很干扰,但是毫无作用。常见的百度统计有这样一些cookie: Hm_Lpvt开头和Hm_lvt开头的,当然一般Hm_开头的大概率百度统计的,其他的大家自己在做的过程中去做总结,这里就不一一解释了。 然后我们继续分析,再次请求下这个api,获取请求是的cookie值:
aliyungf_tc=AQAAAJglyDOjpQwAVYYKcPUhPe30XE/a;
xq_a_token=a8d434ddd975f5752965fa782596bd0b5b008376;
xq_a_token.sig=ke78qTMMk1J4blZPe-jY53Uy9Ec;
xq_r_token=437547d929e3cc54630bfd58136879694e1ae4a9;
xq_r_token.sig=iYuNwCitZuVpyfkOu6_LLtaQn6E;
u=781511537516883;
device_id=a4d5e9838df630d4ed110e85576d0482;
Hm_lvt_1db88642e346389874251b5a1eded6e3=1511537517;
Hm_lpvt_1db88642e346389874251b5a1eded6e3=1511537543
我们发现,除了u和百度统计的值在变之外,其他的值是不变的,而这些变的值并不影响成功请求数据。(进一步验证你会发现它只会验证xq_a_token这个值)
xq_a_token=a8d434ddd975f5752965fa782596bd0b5b008376;
有的时候这个xq_a_token值是需要在首页获取的,这个可以参考爬虫课程(十一)|知乎:使用Scrapy模拟登录知乎文章中提到的获取_xsrf的方法。
三、扩展:破解cookie反爬策略方法论
通过Cookie设置反爬策略确实属于反反爬中相当难的点,,那我们遇到这种Cookie反爬是应该怎么办呢?我简单说下我们处理的思路。
- 1、先删掉Cookie看正不正常的 第一步也是最重要的一步,千万记得先把Cookie都删掉请求一次,如果没问题,万事大吉。这里注意对于Cookie来说一定要把环境处理好,因此测试之前一定记得点开『打开新的隐身窗口』的选项。每次测试完了,打开控制界面,清空Cookie再做下一次测试。
- 2、再就是确定这些Cookie值是否是固定不变的 如果这些cookie中的值固定不变,那也一样万事大吉。
- 3、找出变数,再找Response中的Cookie 如果不行,咱们就开始找这些Cookie是怎么来的,首先不少的Cookie都是Http Reponse里返回的,那么清理掉Cookie,刷新页面,点开network的标签页,一个一个请求点下去,很快就会发现是哪个请求返回的,当然从我这边的经验来说,这些cookie都是从首页设置的。
- 4、找Javascript的关键字 如果还没找到,咱们就进行下一步:找到Cookie中比较特别的词(比如_xsrf、xxxtoken等等)。用这个词去主要的Javascript文件中搜索。一般来说会找到文件中具体是哪一句设置的,如果这个逻辑看着很复杂,可以在这一句打断点调试来判断这个Cookie到底如何生成的。
- 5、终极方案Break-on-Access 这个方法我是没试过,也是从别人文章中看到的,下次我用上了在补吧。
- 一斤代码深入理解系列(四):微信小程序和服务器通信-WebSocket
- linux学习第十四篇:查看磁盘,文件大小命令:df,du;磁盘分区
- 二叉树的性质和常用操作代码集合
- linux学习第十五篇:磁盘格式化,磁盘挂载,手动增加swap空间
- 《Java程序设计基础》 第8章手记Part 2
- 备忘录模式
- 《Java程序设计基础》 第8章手记Part 1
- 你很有想法,跟我学做菜吧No.3
- 《数据结构》 定长顺序串常用操作代码集合
- 一斤代码深入理解系列(七):微信小程序中使用微信风格样式库-WeUI
- 餐厅老板要累疯了No.2
- linux学习第十九篇:压缩介绍,gzip,bzip2,xz压缩工具
- 区块链?黑人问号?NO.1
- linux学习第二十一篇:安装软件包的三种方法,rpm,yum工具用法,yum搭建本地仓库
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 在java中notify和notifyAll的区别
- 我在近期求职中遇到的前端面试问题及其解法
- 腾讯云 云开发 部署 Blazor网站
- 最新基准测试:Kafka、Pulsar 和 RabbitMQ 哪个最快?
- 基于飞桨实现高光谱反演:通过遥感数据获取土壤某物质含量
- 飞桨Tracking目标跟踪库开源!涵盖业界主流的VOT算法,精准检测动态目标轨迹
- 基于react的组件库主题设计方案
- Xilinx MPSoC PS/PL之间的数据交互和外设设计
- 基于Res-Unet网络实现肝脏肿瘤分割任务
- golang判断map中key是否存在的方法
- 迁移实战:一次AntDB(基于pgxl分布式架构的数据库)数据库迁移经验分享
- 看完这篇文章,99%的人都会使用Mysql Explain工具
- 浅析MySQL存储引擎序列属性
- 详述MySQL Using intersect交集算法
- 案例:强制开库遭遇ORA-16433的处理过程