Python之JS反爬

一般情况下,我们要获取一些登录后的数据,就需要通过代码去模拟登录。那么响应某位朋友的留言请求,啥时候讲讲JS呀!于是乎我就选择了一个考点非常 nice 的网站——人人网。那今天我们通过模拟登录人人网,来跟大家唠唠大家都非常期待的JS反爬。

解析人人网

那么爬虫的第一步千万不要着急写代码,而是对页面进行分析。此处我们选择使用谷歌的无痕浏览器(每次重新打开都会清理缓存)
如何打开谷歌无痕:

  • 1.打开谷歌浏览器
  • 2.如图

在这里插入图片描述
然后通过无痕浏览器打开人人网

  • 人人网url:http://www.renren.com/

在这里插入图片描述
接下来需要对登录页面做解析,所以可以通过以下几种方式打开谷歌开发者工具

  • F12 键
  • 鼠标右键下的检查

在这里插入图片描述
然后我们需要去进行登录测试,如下GIF

  • 输入伪账号与密码
  • 点击登录
  • 并观察右侧的 Network 中的请求地址变化
  • 看到 http://www.renren.com/ajaxLogin/login?1=1&uniqueTimestamp=2020641655904
  • 点击进去,看到其 headers

在这里插入图片描述
进行剖析,发现以下结果

  • 登录请求为 Post 请求
  • Post 请求所携带的参数

在这里插入图片描述
我们会发现用户输入的 用户名及密码 奥哟~居然是明文,并且这个请求的参数也没有什么加密的或者说变化的参数。

按照这个推理,实际上我们直接通过 requests 库发送 Post 请求,并将 From Data 中的值传过去不就 OK了?伪代码如下:

import requests

url = "http://www.renren.com/ajaxLogin/login?1=1&uniqueTimestamp=2020641533756"
data = {
    "email": "Logic_Juran",
    "password": "123456",
    "icode": "origURL: http://www.renren.com/home",
    "domain": "renren.com",
    "key_id": 1,
    "captcha_type": "web_login"
}

requests.post(url=url, data=data)

但是,真相真的如此简单吗?当然不是。

首先,我填入真实的账号密码[额,不要给我打电话]…大家会发现页面进行了跳转,所以我们找不到 login 所对应的网站

在这里插入图片描述

那要怎么做到页面跳转时,Network 中的 url 不进行刷新而是添加呢?小技巧,勾上以下选项。

在这里插入图片描述
再退出重新登录会发现如下

  • 密码加密为:****32e0725f6d0566f8c04c773467a10cea3411adda345d2656b348e6683585
  • rkey 登场:a63d4c171d299d57332099687542d201

在这里插入图片描述
也就说是,在不清理缓存的情况下不是第一次登录时密码就会加密以及 rkey 会出现。此刻,我们需要了解 rkey 是否是每次都变化的。

  • rkey 不变:则直接拷贝到 data 中请求即可
  • rkey 变:我们就需要来破解 rkey 是如何生成的

在这里插入图片描述
经过对比,我们发现 password 与 rkey 在每次登录的时候都会发生变化。但是怎么找到与其相关的文件呢?

首先我们可以观察登录按钮是否有绑定JS事件

  • 回到登录页面
  • 输入账号密码
  • 打开开发者工具中的 elements
  • 点击 登录 观察开发者工具中的 Event Listeners
  • 加载出 bi-sdk.1.2.1.js

在这里插入图片描述
往 bi-sdk.1.2.1.js 里头搜索 rkey
在这里插入图片描述
再全局搜索 rkey ,也没有找到~

在这里插入图片描述
这可咋整呢?此时,我们需要切换思路,如果说 PC 端严防把守,那我们可以选择使用 APP 端来做这个事情。如下图,选中按钮。

在这里插入图片描述
在进行伪登录,我们会发现出现了 rKey 以及 clog 两个文件,并且其 initiator 为celllog.js

在这里插入图片描述
于是,点击进去看到其 js 代码,并且双击 {} 将 js 代码进行 js 格式化,方便我们后续操作。

在这里插入图片描述

观察Js的执行过程

既然找到了 js 的位置,我们就可以来通过观察 js,找到 js 具体在如何执行,再通过 python 程序来模拟 js 的执行,或者是使用类似 js2py 直接把 js 代码转化为 python 程序去执行,来模拟 rkey 以及 password 的变动情况。

观察 js 的执行过程最简单的方式是添加断点

在这里插入图片描述
在左边行号点击即可添加,对应的右边 BreakPoints 中会出现现有的所有断点,然后继续点击登录,每次程序在断点位置都会停止,通过如果该行有变量产生,都会把变量的结果展示在Scoope中

在这里插入图片描述
在上图的右上角有1,2,3三个功能,分别表示:

  • 1:继续执行到下一个断点
  • 2:进入调用的函数中 (由此可以发现 password 加密的 js 文件
  • 3:从调用的函数中跳出来
破解JS

在知道了 js 如何生成我们想要的数据之后,那么接下来我们就需要想方设法的去使用 Python代码 模拟 JS 代码 对数据的加密。但是,果真需要我们一行一行的模拟吗?并不需要,强大的 Python 已经封装了很多对 JS 代码块进行翻译的工具,今天我们着重讲解 js2py。

js2py介绍

js2py是一个js的翻译工具,也是一个通过纯python实现的js的解释器,github上源码与示例

使用它需要通过 pip install js2py 进行安装。

使用 js2py 获取参数

虽然不需要一行一行的去解析 JS 代码,但是实现 JS 的破解,仍然需要大家有基本的 JS 阅读能力。所以,我们现在来剖析一下登录的 JS 代码

formSubmit: function() {
        var e, t = {};
        $(".login").addEventListener("click", function() {
            t.phoneNum = $(".phonenum").value,
            t.password = $(".password").value,
            e = loginValidate(t),
            t.c1 = c1 || 0,
            e.flag ? ajaxFunc("get", "http://activity.renren.com/livecell/rKey", "", function(e) {
                var n = JSON.parse(e).data;
                if (0 == n.code) {
                    t.password = t.password.split("").reverse().join(""),
                    setMaxDigits(130);
                    var o = new RSAKeyPair(n.e,"",n.n)
                      , r = encryptedString(o, t.password);
                    t.password = r,
                    t.rKey = n.rkey
                } else
                    toast("公钥获取失败"),
                    t.rKey = "";
                ajaxFunc("post", "http://activity.renren.com/livecell/ajax/clog", t, function(e) {
                    var e = JSON.parse(e).logInfo;
                    0 == e.code ? location.href = localStorage.getItem("url") || "" : toast(e.msg || "登录出错")
                })
            }) : toast(e.msg)
        })
    }

从以上代码我们得知一下信息:

  • 我们要登录需要对密码进行加密和获取rkey字段的值
  • rkey字段的值我们直接发送请求rkey请求就可以获得
  • 密码是先反转然后使用RSA进行加密, js代码很复杂, 我们希望能通过在python中执行js来实现
具体实现思路
  • 使用 session 发送 rKey 获取登录需要信息
    • url: http://activity.renren.com/livecell/rKey
    • 方法: get
  • 根据获取信息对密码进行加密
    • 准备用户名和密码
    • 使用 js2py 生成 js 的执行环境:context
    • 拷贝使用到 js 文件的内容到本项目中
    • 读取 js 文件的内容,使用 context 来执行它们
    • 向 context 环境中添加需要数据
    • 使用 context 执行加密密码的js字符串
    • 通过 context 获取加密后密码信息
  • 使用 session 发送登录请求
    • URL: http://activity.renren.com/livecell/ajax/clog
    • 请求方法: POST
    • 数据:
phoneNum: xxxxxxx
password: (加密后生产的)
c1: 0
rKey: rkey请求获取的

分析就到这里了奥~具体代码请关注公众号:极客夜读

或者直接扫码关注奥~

在这里插入图片描述

  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值