asxe
asxe

# 前戏

之前的博客由于太久没有维护,又懒得翻新了,所以索性重新搭建了一个,看着主页空荡荡的,所以随便写一篇 js 逆向爬虫,这次的 “受害者” 是红人点集。
废话不多说,教程开始。
网址: 网址

# 正片

# 逻辑分析

打开控制台,刷新网页,在网络记录里选择 XHR 类(别问,问就是 Ajax),可以看到一个 api 如下 (图片有点糊,将就一下吧)
1.jpg

点开 api 的表单数据,可以看到
2.jpg

对这几个参数,param 和 tenant 不用说肯定是定值,对于 signtimestamptoken 则有可能是加密变化参数,(不要忘了,对于 token,有可能是定值,例如登录账号后会生成一个此账号的固定 token),对页面进行多次刷新,比对可以发现 token 确实是不变的,仅是 sign timestamp 变化。
则搜索源代码 sign,即可找到 sign 在代码中的位置,如下(搜索找位置此处省略)
3.jpg

可以看到四个参数都在,并且参数值为变量,则可以判断是此处无疑
sign 处打上断点(timestamp 打也是一样的),刷新网页,此时页面停在断点处(再次证明此处代码是要找的)
将鼠标停在加密 sign E 函数上,则可跳转到 E 函数(省略图片),如下
4.jpg

发现 E 函数是返回了一个值,这个值是通过 k 函数进行加密的,于是用同上方法跳转到 k 函数,如下
5.jpg

# 逻辑梳理

看到整个加密逻辑了过后,来进行一遍梳理,并运用 python 模拟加密逻辑
其中 timestamp 为时间戳,即

time_get=str(int(time.time())*1000)

对于 sign, 我们先分析 k 函数k 函数是对传入的参数进行 sha256 加密,即

sha256加密
def sha256(self,value):
        sha=hashlib.sha256()
        sha.update(value.encode('utf-8'))
        return sha.hexdigest()

E 函数则是将 param,timestamp,tenant,salt 进行拼接并返回其进行 sha256 加密的值(对于 salt 的值,即 C,可以将鼠标放在上面查看)
注:此处拼接结果为

拼接结果
time_get=str(int(time.time())*1000)
        params={"no":"dy0002","data":{"days":1,"rankType":7}}
        dd=json.dumps(params)
        text = f'param={dd}&timestamp={time_get}&tenant=1&salt=kbn%&)@<?FGkfs8sdf4Vg1*+;`kf5ndl$'

其中 text 则为拼接结果

# 结果

最后请求 api 的时候带上 headers 和表单数据,即可返回 json 类型的数据,对数据进行处理即可,效果图如下:
5.jpg

# 完整代码

代码中的 token 值请各位自行登录获取

import requests
import hashlib
import time
import json
class Spider:
    def __init__(self):
        self.api='https://ucp.hrdjyun.com:60359/api/dy'
        self.headers={
    "Accept": "application/json, text/plain, */*",
    "Accept-Encoding": "gzip, deflate, br",
    "Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6",
    "Connection": "keep-alive",
    "Content-Length": "248",
    "Content-Type": "application/json;charset=UTF-8",
    "Host": "ucp.hrdjyun.com:60359",
    "Origin": "http://www.hh1024.com",
    "sec-ch-ua": "\"Not_A Brand\";v=\"99\", \"Microsoft Edge\";v=\"109\", \"Chromium\";v=\"109\"",
    "sec-ch-ua-mobile": "?0",
    "sec-ch-ua-platform": "\"Windows\"",
    "Sec-Fetch-Dest": "empty",
    "Sec-Fetch-Mode": "cors",
    "Sec-Fetch-Site": "cross-site",
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36 Edg/109.0.1518.52"
}
    def sha256(self,value):
        sha=hashlib.sha256()
        sha.update(value.encode('utf-8'))
        return sha.hexdigest()
    def spider(self):
        time_get=str(int(time.time())*1000)
        params={"no":"dy0002","data":{"days":1,"rankType":7}}
        dd=json.dumps(params)
        text = f'param={dd}&timestamp={time_get}&tenant=1&salt=kbn%&)@<?FGkfs8sdf4Vg1*+;`kf5ndl$'
        sign =self.sha256(text)
        data={
            "param":dd,
            "sign":sign,
            "tenant":"1",
            "timestamp":time_get,
            "token":"你的token"
        }
        session=requests.session()
        session.headers=self.headers
        response=session.post(self.api,data=json.dumps(data))
        print(response.json())
        if response.json().get('status') == 0:
            data = response.json().get('data')['rankList']
            for d in data:
                items = {}
                items['抖音名'] = d.get('anchorName')
                items['销量'] = d.get('displaySales')
                items['销售额'] =d.get('displayMoney')
                items['粉丝'] ='%.2f'% (d.get('fans')/10000) +'万'
                items['热度'] =d.get('gmv_score')
                print(items)
if __name__=='__main__':
    Spider().spider()
更新于 阅读次数

请我喝[茶]~( ̄▽ ̄)~*

ASXE 微信支付

微信支付

ASXE 支付宝

支付宝

ASXE 贝宝

贝宝