【爬虫-反爬虫】系列一:反爬虫之session(4)

反爬虫之session(4)

人们经常把session与cookie放在一起谈论,因为session变量存储在服务器端,而cookie是浏览器端,两者在能力上互补。

在讲session之前,先思考一下这样一个场景:

用户A在chrome浏览器打开一个网站,此时A就进入了该网站的一次会话。而网站为了更安全的记录A的会话状态,就会把这些状态存在服务器端,也就是session中(毕竟客户端的cookie并不太安全),假设存储记录为record-A。

此时用户B也在访问网站,服务器也会在session中保存一条record-B来存放B的会话状态。

那么问题就是,服务器怎么知道每次应该更新哪一条record呢?换句话说,服务器必须知道当前请求来自于用户A还是用户B?亦或是未知用户?

这个时候你可能指望在请求链接中传入每个用户id,这样服务器就能区分用户了,但这样并不安全,因为请求连接是可以随意更改的。

在回答这个前,要引入一个极其重要的概念:SESSIONID。

SESSIONID

SESSIONID是一个字符串,也是一个贯穿cookie与session之间的一个概念。

当你第一次打开网站时,会分配一个全局唯一的SESSIONID(如果开启了session),并且存放在cookie中,每次发送请求时,这个SESSIONID会放在cookie中一起发送给服务器。

这时服务器就能根据SESSIONID分辨请求来自于哪一个会话了,然后也会很聪明的把SESSIONID-A对应record-A,SESSIONID-B对应record-B。

当用户关闭chrome浏览器后,本次会话结束,再次打开网站时会生成新的SESSIONID,这也就不难理解为什么服务端会清理长时间未使用过的SESSIONID记录。

因为SESSIONID只存在于用户当前会话中,所以安全性还是有的,除非用户被网络劫持导致泄露了该SESSIONID,一般情况下都不会有啥问题。

提醒一下,并不是所有网页都会使用session,一般涉及到注册,登录的业务网站才用。(PS:对于php来说,使用了session_start()则表示开启session)

一般来说,PHP网站的SESSIONID名为PHPSESSID,JSP网站的SESSIONID名为JSESSIONID,如下所示。

所以以后你看到cookie里存在这种数据也就不会奇怪了。

理解了SESSIONID就能解释很多东西了,而SESSIONID又存储在cookie中,本质上只要把握住了cookie,也就能模拟真实请求。

SESSIONID如何反爬虫?

因为服务器能通过SESSIONID判断你的状态,所以你很难模拟别人登录(因为你不知道对方的SESSIONID)。当然,如果你能获取到别人的SESSIONID或者全部cookie(常见的方式就是使用Wi-Fi进行流量劫持),就能轻而易举地模拟别人登录。

举两个使用SESSIONID反爬虫的应用场景:

在登录场景下,通过SESSIONID,服务器会在对应session中存放用户登录状态。

在注册场景下,验证码值会存储在对应session中,常见的验证流程简化如下:提交验证码+SESSIONID=》服务器根据SESSIONID找到对应session=》服务器从session中取出正确的验证码值=》比较验证码。

在注册场景下,必须保持请求都在同一个会话下完成,也就是:获取验证码图片的请求与提交验证码注册的请求必须处于同一个会话下。

模拟多个请求在同一个session下访问

在Python下,每个请求都是一次全新的会话,都会生成新的SESSIONID。

那么怎么让多个请求伪装在同一个session内呢?

解决方法很简单,将首次请求的SESSIONID提取出来,后续请求都使用此SESSIONID即可。

一个简单的代码示例:

将提取出来的SESSIONID填入接下来的请求cookie中即可。

本文讲的是关于session反爬虫方面的基础应用,很多网站会做些改变,这样可以起到一定迷惑作用,但本质上只要把握了cookie,就能轻松应对。