Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

有关抓取桃叭订单的事项 #1

Open
MskAdr opened this issue Mar 18, 2020 · 11 comments
Open

有关抓取桃叭订单的事项 #1

MskAdr opened this issue Mar 18, 2020 · 11 comments

Comments

@MskAdr
Copy link

MskAdr commented Mar 18, 2020

看到你用了我的抓取桃叭数据的代码,提示一下未登录的情况下只能抓取订单模型,登录了以后可以抓取全部订单数据,不过好像是乱序的。
新的代码我写在了https://github.com/MskAdr/433QQBot/blob/master/Taoba.py 这里,用了SQLAchemy做数据库的处理。
这个是从网页版订单退款的列表里面抓取的,要先登录才行。

@41xu
Copy link
Owner

41xu commented Mar 18, 2020

你是桃叭后台程序员吗,那个加密解密如果是自己破译出来的话..真的🐂

@41xu
Copy link
Owner

41xu commented Mar 18, 2020

但是你的代码风格我不喜欢所以只参考你的encode,decode,写完了会加ref的(:D

@MskAdr
Copy link
Author

MskAdr commented Mar 18, 2020

不是,用Chrome开发者工具从前端的js抓出来的
废了点劲。抓了一天🤦‍♂️

@41xu
Copy link
Owner

41xu commented Mar 18, 2020

tql, 那个加盐的密钥是咋抓出来的啊,真的好好奇我只能推测出来zlib和base64Orz
另,我抓购买订单的时候选择的是join页面,并没有需要登录信息也没有出现乱序的情况,不晓得你说的全部订单数据是指什么在哪里可以看见。

@41xu
Copy link
Owner

41xu commented Mar 18, 2020

以及感觉你的第一开发语言应该不是python吧🤪有些不pythonic啦!(猜测或许是...go?scala?还是Java?23333🤣 总之那个加盐混淆的密钥我是真的看傻了!

@MskAdr
Copy link
Author

MskAdr commented Mar 19, 2020

从js用开发者工具调试出来的,其实我是写C++搞ACM的,Python连书都没看过,纯属应援会有需要硬上的。
一般来说开发者工具可以看到每个http请求是通过哪条js语句发出来的,或者再搜一下POST时候的关键字段,这个一般都是不会被混淆的。然后通过调用栈看看前后的代码,基本就是个体力活,难也没多难,耐心就好。
就按照桃叭这个举例,我当时是这么做的。
首先肯定是用浏览器的开发者工具看一下请求报文,看见报文后面有几个等号可以猜测是base64。但直接解码base64发现不太行,解出来是一串乱码,所以肯定是base64编码的什么东西。
接下来根据开发者工具提供的发起请求的js文件定位,找到相关的js文件,设置一个断点,从调用栈一层一层往上看,看看核心的编解码在哪个js文件,不过当时看了半天没什么成果,但调用栈里面就那几个文件,主要就是index什么什么和chunk什么什么两个文件,所以换个思路考虑一下。
base64里面不会有$,而且$前面是个数字,所以猜测$应该是个连字符,然后在这两个文件分别搜索"$"和'$',看看有什么结果,然后就在index那个js文件里面有突破了,找到了这么一行:
return n + "$" + uni.arrayBufferToBase64(i.raw)
可以猜测这就是加密的核心代码,然后从这行上下文接着看,发现这样几句:

g = {
    init: l,
    compress: u,
    uncompress: c,
    encrypt: f,
    decrypt: p
};

可以确定这个f函数就是核心的加密,在上面找到的return那里设置一个断点,然后发现f函数的参数就是明文,return的结果就是密文。接下来就是体力活了,单步执行f函数,看看每一步都是做什么的。

f = function(e) {
    var t = new s.default(3 * e.length),
        n = t.writeString(e);
    t = t.slice(0, n), t = u(t);
    var i = d(t, o);
    return n + "$" + uni.arrayBufferToBase64(i.raw)
}

在函数的入口设置一个断点,然后分步执行,然后看到t是一个数组,正好数组的每一个值按顺序都是明文的ascii码,u是压缩函数,u的代码里面有try-catch块,catch里面的信息有zlib,所以猜测是zlib压缩,然后是d函数,调进去看了一下d函数就是间隔异或的功能,字符串o是硬编码写在js文件里的,就是"%#54$^%&SDF^A*52#@7"。最后就是把结果转成base64,在前面加上长度头。
把逻辑理顺了以后拿Python把过程复现一下,然后拿已知的明文和密文试验一下,发现逻辑没问题,再发一次post请求试试,然后得到了正确的返回值,就可以了。

@MskAdr
Copy link
Author

MskAdr commented Mar 19, 2020

全部订单信息要拿应援会的账号登录以后才能看见,登录以后点活动经费进去,有详细名单下载,不过是xlsx格式的,但是还有一个退款入口,从退款入口可以看见一个项目的全部订单,只不过看起来是乱序的,所以每次更新必须得全部爬一遍才行。

@41xu
Copy link
Owner

41xu commented Mar 20, 2020

从js用开发者工具调试出来的,其实我是写C++搞ACM的,Python连书都没看过,纯属应援会有需要硬上的。
一般来说开发者工具可以看到每个http请求是通过哪条js语句发出来的,或者再搜一下POST时候的关键字段,这个一般都是不会被混淆的。然后通过调用栈看看前后的代码,基本就是个体力活,难也没多难,耐心就好。
就按照桃叭这个举例,我当时是这么做的。
首先肯定是用浏览器的开发者工具看一下请求报文,看见报文后面有几个等号可以猜测是base64。但直接解码base64发现不太行,解出来是一串乱码,所以肯定是base64编码的什么东西。
接下来根据开发者工具提供的发起请求的js文件定位,找到相关的js文件,设置一个断点,从调用栈一层一层往上看,看看核心的编解码在哪个js文件,不过当时看了半天没什么成果,但调用栈里面就那几个文件,主要就是index什么什么和chunk什么什么两个文件,所以换个思路考虑一下。
base64里面不会有,而且前面是个数字,所以猜测应该是个连字符,然后在这两个文件分别搜索""和'$',看看有什么结果,然后就在index那个js文件里面有突破了,找到了这么一行:
return n + "$" + uni.arrayBufferToBase64(i.raw)
可以猜测这就是加密的核心代码,然后从这行上下文接着看,发现这样几句:

g = {
    init: l,
    compress: u,
    uncompress: c,
    encrypt: f,
    decrypt: p
};

可以确定这个f函数就是核心的加密,在上面找到的return那里设置一个断点,然后发现f函数的参数就是明文,return的结果就是密文。接下来就是体力活了,单步执行f函数,看看每一步都是做什么的。

f = function(e) {
    var t = new s.default(3 * e.length),
        n = t.writeString(e);
    t = t.slice(0, n), t = u(t);
    var i = d(t, o);
    return n + "$" + uni.arrayBufferToBase64(i.raw)
}

在函数的入口设置一个断点,然后分步执行,然后看到t是一个数组,正好数组的每一个值按顺序都是明文的ascii码,u是压缩函数,u的代码里面有try-catch块,catch里面的信息有zlib,所以猜测是zlib压缩,然后是d函数,调进去看了一下d函数就是间隔异或的功能,字符串o是硬编码写在js文件里的,就是"%#54$^%&SDF^A*52#@7"。最后就是把结果转成base64,在前面加上长度头。
把逻辑理顺了以后拿Python把过程复现一下,然后拿已知的明文和密文试验一下,发现逻辑没问题,再发一次post请求试试,然后得到了正确的返回值,就可以了。

哇这个厉害了,学到了。我用的Request Payload就已经是加密过的然后有些迷茫,之后根据请求头推断应该是先zlib之后base64加密,加盐不像你那样调用确实看不出来Orz 👍🏾👍🏾👍🏾tql

@41xu
Copy link
Owner

41xu commented Mar 20, 2020

全部订单信息要拿应援会的账号登录以后才能看见,登录以后点活动经费进去,有详细名单下载,不过是xlsx格式的,但是还有一个退款入口,从退款入口可以看见一个项目的全部订单,只不过看起来是乱序的,所以每次更新必须得全部爬一遍才行。

这个位置我们对爬去项目订单处理的方式可能不同,我就直接使用的join那个请求,存了前一次爬取的response['data']之后和这次爬去的对比,爬到的订单是按照排名的顺序爬下来的,不过确实每次更新都要爬一遍,这个没有类似于摩点和小经费的评论区播报最新一次的集资那种就有点麻烦Orz

@41xu
Copy link
Owner

41xu commented Mar 20, 2020

这个github账号是你的大号吗👀大号的话我就点关注了!

@MskAdr
Copy link
Author

MskAdr commented Mar 20, 2020

是大号。
我之前也是每次爬取一轮排名,然后做差这样做的。之前抓o-what的时候就是这么写的,缺点就是有人短时间内集资多次的话会被识别成一个,不过优点就是不用拿发布者的账号登录,所以各有利弊吧。
而且用账号登录还有一个优点就是可以自动添加项目,通过接口直接抓取这个账号的主人发布了什么项目,然后和数据库已有的项目对比,直接添加。
我们的饭头比较XX,之前经常是项目上线了一段时间才联系我,加了这个功能我就省心多了。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants