吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 2488|回复: 5
收起左侧

[Python 转载] [Scrape Center - spa2]含加密参数的动态网页爬取

[复制链接]
三滑稽甲苯 发表于 2022-2-17 15:35

网址

主站:https://scrape.center/
题目:https://spa2.scrape.center/

前言

这个题目和 spa1 很像,但是难度大了很多,因为它有加密参数。但是俗话说得好,功夫不负有心人,只要坚持一定能够拿下它。

分析

找到 api 接口,发现相较于 spa1 多了一个 token 参数,那么我们只要找到生成 token 的方法即可。

1

1
查看它的请求调用堆栈,第一个直接点进去,然后格式化

2

2

3

3

下了断点后发现 unulld 就是一个普通的 XMLHttpRequest ,并且这个 js 里区分大小写搜索 token 后没有出现类似于 limit: xxx, offset: xxx, token: xxx 的结构,那大概率是找错地方了

4

4

带有 :formatted: 肯定是查看过的 js ,那么接下来看看没有 :formatted: 的 js 。

5

5

跟进去,是不是看到了很熟悉的结构?

6

6

params: {
    limit: this.limit,
    offset: a,
    token: e
}

接下来只需要下个断点,看看 e 是怎么出来的就好了

7

7
点击第 2 页,看看断到了什么
Object(i["a"]) 是一个函数

8

8

同时可以猜测 this.$store.state.url.index 是一个定值

9

9

a 就是简简单单的一个 offset 。
跟进 Object(i["a"]) ,格式化,计算 token 的函数终于映入眼帘

10

10

猜测 n 指代的就是 cryptojs ,这个很容易验证,接下来只要把 js 转为 Python 就好了。
把代码复制下来,进行“翻译”

function i() { // arg: '/api/movie', offset
    for (var t = Math.round((new Date).getTime() / 1e3).toString(), e = arguments.length, r = new Array(e), i = 0; i < e; i++)
        //   t = str(int(time()))                                   e = len(args) # 2     r = [?, ?]        for i in range(e)
        r[i] = arguments[i]; // r[i] = args[i]
    r.push(t); // r.append(t)
    var o = n.SHA1(r.join(",")).toString(n.enc.Hex)
    // o = sha1(','.join(str(item) for item in r).encode()).hexdigest()
    //                    ↑ 这里不套一层 str 会导致 Python 报错
      , c = n.enc.Base64.stringify(n.enc.Utf8.parse([o, t].join(",")));
      //c =              b64encode(f'{o},{t}'.encode('utf-8')        ).decode()
      //                 stringify 应该包括了 b64encode 和 decode 两个操作
    return c
}
// token = i("/api/movie", offset)

完整的生成 token 代码

def generate_token(*args) -> str:
    t = str(int(time()))
    e = len(args)
    r = [None, None]
    for i in range(e):
        r[i] = args[i]
    r.append(t)
    o = sha1(",".join(str(item) for item in r).encode()).hexdigest()
    c = b64encode(f"{o},{t}".encode("utf-8")).decode()
    return c

最后在原来代码的基础上添加参数 token=generate_token("/api/movie", offset) 即可使用。

完整代码

from requests import Session
from time import time
from hashlib import sha1
from base64 import b64encode

def show(movies: list):
    for movie in movies:
        print(f"{movie['name']} - {movie['alias']}")
        print("  Score:", movie["score"])
        print("  Tags:", *movie["categories"])
        print("  Regions:", *movie["regions"])
        print(f'  Duration: {movie["minute"]} min')
        print("  Release date:", movie["published_at"])
        print("  Link:", f"https://spa2.scrape.center/detail/{movie['id']}")
        print()

def generate_token(*args) -> str:
    t = str(int(time()))
    e = len(args)
    r = [None, None]
    for i in range(e):
        r[i] = args[i]
    r.append(t)
    o = sha1(",".join(str(item) for item in r).encode()).hexdigest()
    c = b64encode(f"{o},{t}".encode("utf-8")).decode()
    return c

if __name__ == "__main__":
    start = time()
    x = Session()
    LIMIT = 10  # 每次最多获取10条数据
    URL = "https://spa2.scrape.center/api/movie/"
    r = x.get(
        URL, params={"limit": 1, "offset": 0, "token": generate_token("/api/movie", 0)}
    )
    TOTAL = r.json()["count"]
    offset = 0
    while offset < TOTAL:
        r = x.get(
            URL,
            params={
                "limit": LIMIT,
                "offset": offset,
                "token": generate_token("/api/movie", offset),
            },
        )
        show(r.json()["results"])
        offset += LIMIT
    end = time()
    input(f"Time used: {end - start} s.")

效果图

11

11

免费评分

参与人数 1吾爱币 +7 热心值 +1 收起 理由
苏紫方璇 + 7 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

Xw丶小威 发表于 2022-2-17 16:55
学到了。真好。
君月栩 发表于 2022-2-17 17:39
tt5200 发表于 2022-2-17 17:45
998858 发表于 2022-2-17 18:19
收藏起来先,以后用到
cflying 发表于 2022-2-17 21:24
看看,学学
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-25 07:28

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表