爬取知乎数据 - 模拟登录

平时逛各大开发论坛、社区等,看到很多讨论爬取知乎数据的帖子。我也对此也有浓烈兴趣,正好最近学了python,拿来练手

再合适不过了,之后还可以拿这些数据去学习数据分析。

看到很多人都拿知乎 Web 端来爬取数据。这完全是没有问题的,但前端的网页结构很容易发生改变,只要一变,意味着代码也要变动。维护起来也就很频繁,很麻烦了。

但是,现在 IOS、Android 这样的移动端大行其道。而移动端的数据传递都是Json这样很规范的数据格式。数据规范,完整,便于我们爬取,也利于维护。所以这个系列文章使用移动端来爬取数据。

准备

  1. 一台 Android 设备或虚拟机(我这里使用 红米2A MIUI6 Android4.4 没有使用7.0以上版本的 Android,是方便抓取 HTTPS 请求)

  1. 抓包工具,这里使用 Charles
  2. Android 反编译开源工具 jadx

步骤

移动端登录并抓取请求

分析登录请求

从图中可以得知登录请求地址是https://api.zhihu.com/sign_in

很重要的参数是 header 里的 Authorization Cookie 和 post 请求中的signature

header 里的其他参数都可以写死,之后的请求都带上就可以。

动态参数的获取

  1. Cookie,因为我们使用 python 的 requests 库,所以直接用它的 session 来处理。

  2. Authorization,如果没有此值会报如下错误

    1
    {'error': {'message': '未设置验证方式', 'code': 602}}

    不过,目前登录可以写死这个值。登录后会有一个asscess_token,之后的请求 header 中的Authorization都填入这个值才可以。

  3. signature,这是个签名。如果没有签名或签名错误,会报如下错误

    1
    2
    {'error': {'message': 'Missing argument signature', 'code': 400}}
    {'error': {'message': 'Client authentication failed.', 'code': 602}}

    所以,现在出现了一个难点,无法仿造这个签名。因为不知道这东西怎么生成的,用的哪种加密方式,加密的字段是什么,都不知道。但是,我们知道请求是从 Android 客户端发出的,加密方式肯定就在其中。

    这时候,我们就必须反编译知乎的 APK 文件,去找它的签名方式。

    官网下载 APK,使用之前准备的 jadx反编译

    1
    JAVA_OPTS="-Xmx4G" jadx -j 1 -d zhihu futureve-mobile-update-release-4.18.0(477).apk

    我们使用 IDE 或编辑器打开反编译后的项目

    打开文件 com/zhihu/android/api/model/Authorisation.java

    看到很关键的两个值client_idclient_secret。还有签名的生成方式,里面的参数都可以从之前抓包的请求 header 和 Post 的参数中拿到。

    1
    2
    3
    4
    grantType = 'password'
    str = client_id = '8d5227e0aaaa4797a763ac64e0c3b8'
    authorisation.source = 'com.zhihu.android'
    valueOf = 当前时间戳

    还有签名的算法,打开文件com/zhihu/android/api/util/b.java

    可以看到签名算法是sha1,使用 Python 模拟生成 signature

    1
    2
    3
    4
    5
    6
    7
    8
    def login_signature(key, data):
    msg = data['grant_type'] + data['client_id'] + data['source'] + str(int(time.time()))

    data['signature'] = hmac.new(
    bytes(key, 'utf-8'),
    bytes(msg, 'utf-8'),
    hashlib.sha1
    ).hexdigest()

    登录部分已完成,此项目gavin66/zhihu_crawler 在 Github 已开源。

0%