CSDN博客接口基于java调用的x-ca-signature签名算法研究

这篇具有很好参考价值的文章主要介绍了CSDN博客接口基于java调用的x-ca-signature签名算法研究。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

写在前面

本人业余时间会写写CSDN的博客,查看下博客数据,展现量、阅读量什么的。在“作品数据-单篇文章分析”菜单中可以看到每篇文章的总体展现量、阅读量,要是想看每篇文章每日的访问量需要再次点击列表后边的“查看详情”显示的曲线图,一个一个点击着实有些麻烦,所以想通过调用接口的方式返回数据,把每篇文章的每日数据存起来,再设置个定时任务,就解放双手了。

CSDN博客接口基于java调用的x-ca-signature签名算法研究

找到的参考代码都是python的,没有java的,自己编码后在这里记录一下。

 接口选择

点击“单篇文章分析”,可以得到每篇文章的总体展现、阅读量,那么使用某篇文章的阅读量减去昨天此文章的阅读量,就是每日的访问量了,也不需要调用每篇文章的数据的接口,新建的文章也都能自动获取到了。CSDN博客接口基于java调用的x-ca-signature签名算法研究

head分析

在每次请求接口的时候都会在请求头中传入cookie;x-ca-key;x-ca-nonce;x-ca-signature;x-ca-signature-headers这五个参数。简单的分析不难得出x-ca-key和x-ca-signature-headers是两个固定值,cookie是登录后的标识,会保持数天不变。而x-ca-signature和x-ca-signature-headers 每次请求的时候都不同,这就有点难顶了

CSDN博客接口基于java调用的x-ca-signature签名算法研究

进一步分析

进一步分析下上述5个参数如何生成的,cookie没什么好说的。

通过查看js源代码,搜索x-ca-key的值,看到下边这个方法

CSDN博客接口基于java调用的x-ca-signature签名算法研究

CSDN博客接口基于java调用的x-ca-signature签名算法研究

X-Ca-Key是固定的

X-Ca-Nonce最终通过De函数生成

CSDN博客接口基于java调用的x-ca-signature签名算法研究

X-Ca-Signature由方法名称、url、参数、固定值等计算获得

X-Ca-Nonce生成方法

    private static List<String> chats = new ArrayList<>();

    static {
        //生成 [a, b, c, d, e, f, g, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
        for (int i = 0; i < 7; i++) {
            char c = (char) (i + 97);
            chats.add(String.valueOf(c));
        }
        for (int i = 0; i < 10; i++) {
            char c = (char) (i + 48);
            chats.add(String.valueOf(c));
        }
    }
    /**
     * 获取一次性访问key,参考js方法:
     * De = function() {
          return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (function(e) {
          var t = 16 * Math.random() | 0,
          n = "x" === e ? t: 3 & t | 8;
          return n.toString(16)
      }))}
     *
     * @return
     */
    private static String onceKey() {
        List<String> strs = new ArrayList<>();
        Random rd = new Random();
        for (int i = 0; i < 30; i++) {
            strs.add(chats.get(rd.nextInt(chats.size())));
        }
        return String.format("%s%s%s%s%s%s%s%s-%s%s%s%s-4%s%s%s-9%s%s%s-%s%s%s%s%s%s%s%s%s%s%s%s", strs.toArray());
    }

X-Ca-Signature生成方法

这里特别需要注意的是在生成x-ca-signature时,POST请求和GET请求并不相同,我们需要区分处理。最明显的两个区别是请求方法Method不同,content_type不同,下面POST方法并没有写完

private static String sign(String fullUrl, String method, String onceKey) throws Exception {
        final String ekey = "9znpamsyl2c7cdrr9sas0le9vbc3r6ba";
        final String xcakey = "203803574"; // 开发工具 network 请求头 x-ca-key

        String[] wholdUrl = fullUrl.split("\\?");
        String url, params = "";
        if ("get".equals(method)) {
            url = wholdUrl[0];
            params = wholdUrl[1];
        } else {
            url = wholdUrl[0];
        }
        String _url = url + (!"".equals(params) ? "?" + params : "");
        String to_enc = "";
        if ("get".equals(method)) {
            to_enc = String.format("GET\napplication/json, text/plain, */*\n\n\n\nx-ca-key:%s\nx-ca-nonce:%s\n%s", xcakey, onceKey, _url);
        } else {
//            to_enc = String.format("POST\n%s\n\n{content_type}\n\nx-ca-key:%s\nx-ca-nonce:%s\n%s"
//                    , accept, content_type, xcakey, onceKey, _url);
        }
        return getSHA256StrJava(to_enc, ekey);
    }

    private static String getSHA256StrJava(String content, String secret) throws Exception {
        Mac mac = Mac.getInstance("HmacSHA256");
        SecretKeySpec secret_key = new SecretKeySpec(secret.getBytes(), "HmacSHA256");
        mac.init(secret_key);
       // System.out.println("key: " + secret + " | 内容是:\n" + content);
        byte[] binaryData = mac.doFinal(content.getBytes());
        return Base64.encodeBase64String(binaryData);
    }

执行接口调用

       <dependency>
            <groupId>com.squareup.okhttp3</groupId>
            <artifactId>okhttp</artifactId>
            <version>4.8.1</version>
        </dependency>
   public JSONObject getAllMyArticle() throws Exception {
        String host = "https://bizapi.csdn.net";
        String path = "/blog/phoenix/console/v1/data/single-article-list?action=down&page=1&size=40&type=date";
        String onceKey = onceKey();
        String sign = sign(path, "get", onceKey);
        OkHttpClient client = new OkHttpClient();
        Request request = new Request.Builder()
                .url(host + path)
                .addHeader("Accept", "application/json, text/plain, */*")
                // .addHeader("Accept-Encoding", "gzip, deflate, br") //若有设置,response为乱码
                .addHeader("Accept-Language", "zh-CN,zh;q=0.9")
                .addHeader("Connection", "keep-alive")
                .addHeader("user-agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36")
                .addHeader("origin", "https://mp.csdn.net")
                .addHeader("referer", "https://mp.csdn.net/mp_blog/analysis/article/single")
                .addHeader("sec-ch-ua", "\"Google Chrome\";v=\"105\", \"Not)A;Brand\";v=\"8\", \"Chromium\";v=\"105\"")
                .addHeader("sec-ch-ua-mobile", "?0")
                .addHeader("sec-ch-ua-platform", "\"Windows\"")
                .addHeader("sec-fetch-dest", "empty")
                .addHeader("sec-fetch-mode", "cors")
                .addHeader("sec-fetch-site", "same-site")
                .addHeader("uri-name", "feige")
                //登录后的cokie
                .addHeader("cookie", cookie)
                .addHeader("x-ca-key", "203803574")  //根据浏览器开发者工具请求头设置
                .addHeader("x-ca-nonce", onceKey) //请求1次后作废
                .addHeader("x-ca-signature", sign) // 根据url、排序参数、onceKey、加密key,使用HmacSHA256算法生成的摘要
                .addHeader("x-ca-signature-headers", "x-ca-key,x-ca-nonce") //根据浏览器开发者工具请求头设置
                .build();
        Response response = client.newCall(request).execute();
        response.header("content-type", "application/json;charset=utf-8");
//        出现错误可以将此打开获取报错内容
//        System.out.println(response);
//        System.out.println(response.header("X-Ca-Error-Message"));
        String responseData = response.body().string();
       // System.out.println(responseData);
        return JSONObject.parseObject(responseData);
    }

这里特别注意,生成X-Ca-Signature传入的path是不带域名的,且url的参数部分需要按照字母顺序升序排列,header里其他参数使用浏览器的的,否则容易出错

X-Ca-Signature签名排错方法

打开response的输出,获取header中X-Ca-Error-Message会返回具体的错误信息。如下图会提示正确的签名生成方式,将自己的重新调整就好,因为HTTP Header中无法表示换行,因此返回信息中的换行符都被替换成#,反过来传参时# 号使用 \n 替换

CSDN博客接口基于java调用的x-ca-signature签名算法研究

 总结

需要注意cookie会过期问题。工具本质上不难,就是调用CSDN的接口。难点主要是在于请求头中x-ca-nonce和x-ca-signature这两个参数比较难搞。搞定了这两个参数后面的调用逻辑就比较简单。比如本人使用今天获取的数据与前一天的数据做差,计算出每篇文章昨日访问量数据。文章来源地址https://www.toymoban.com/news/detail-495480.html

到了这里,关于CSDN博客接口基于java调用的x-ca-signature签名算法研究的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 基于.NetCore开发博客项目 StarBlog - (28) 开发友情链接相关接口

    之前介绍的友情链接功能,只实现了友情链接的展示和管理接口。 还缺失友情链接申请、审核管理、通知,现在把这块功能补全。 Model 什么的之前那篇文章都有,本文直接补全逻辑代码~ 详见: 基于.NetCore开发博客项目 StarBlog - (13) 加入友情链接功能 友情链接申请页面 实现一

    2024年02月06日
    浏览(50)
  • Kettle实战案例:拉取CSDN博客列表数据至Excel文件【详细教程】

    本文详细介绍了使用Kettle工具实现拉取CSDN博客列表数据到Excel文件的实战案例,包括接口调用、数据解析、存储过程和实际操作步骤。适用于数据抓取和处理的初学者和专业人士。

    2024年02月02日
    浏览(41)
  • 【ubuntu云服务器部署公网Web抽奖工具】CSDN博客评论区用户抽奖

    送书第一期 《用户画像:平台构建与业务实践》 送书活动之抽奖工具的打造 《获取博客评论用户抽取幸运中奖者》 前几天做了一期送书活动,随着时间流逝,也即将迎来赠书活动抽奖环节,为了活动的公正公开以及可见性,特此开发了一款Web抽奖工具,结合Springboot后台获

    2024年02月08日
    浏览(70)
  • SqlServer2016下载安装步骤详解 SQL Server2016的彻底删除_还能坚持的博客-CSDN博客_sqlserver2016完全卸载

    Windows 下安装sql server 2016(附安装包资源)_极光稻草人的博客-CSDN博客_sql server 2016 安装链接: 链接:https://pan.baidu.com/s/1rPG8Ya4jSbhmHvFCDzTVew  提取码:MXJ0 如果原来以及安装过sqlServer2016或其他版本的,需彻底删除,可参考: 遇到的问题: 1.polybase要求安装orcale jre 7更新 51或更

    2024年02月05日
    浏览(109)
  • 记录一次调用奇门api报错信息Invalid signature (签名无效)

    奇门有msg对应错误的记录 我可能是 3.1   以下是还原场景 第一个方法 第二个方法 以下是运行结果 很奇怪----下第一个打印是正常的,而第二个出现 错误,我对map底层没有特别多的理解 第二个方法修正: 加入代码: 修改MapString,String参数名称为map 这样就正常了

    2024年02月22日
    浏览(50)
  • 基于百度云的 AI 接口调用

      人工智能(Artificial Intelligence),英文缩写为AI。它是研究、开发用于模拟、延伸和扩展人的智能的理论、方法、技术及应用系统的一门新的技术科学。   人工智能是计算机科学的一个分支,它企图了解智能的实质,并生产出一种新的能以人类智能相似的方式做出反应

    2024年01月21日
    浏览(45)
  • Java 调用 WebService 、java调用Soap请求、Java对接soap接口

    工作第一次遇到对接soap接口,觉得有必要记录一下,毕竟踩了不少坑,网上帖子很多但大都不全,也不可能完全满足自己的需求,于是就有了下面的代码: 除了只是借鉴, 注意事项: 1.http://ip:port/xxx/xxx/soap?wsdl有些soap接口,对面是不需要穿?wsdl对接时要问出清 2. httpPost.set

    2024年02月05日
    浏览(52)
  • java调用webService接口

    1、需求: 由于业务需求对接一个比较老的平台使用到了webService接口,这里记录一下调用方法。 一般有三种方式调用webService接口, 1.1、以HttpURLConnection的方式调用 1.2、使用apache-cxf生成java类调用 1.3、使用AXIS调用WebService 我这边主要是使用的是,第三种,使用AXIS调用WebServi

    2024年02月05日
    浏览(45)
  • Java调用HTTP接口

    说明 Java调用HTTP接口可以使用Java的HttpURLConnection或HttpClient等工具 HttpURLConnection HttpClient

    2024年02月08日
    浏览(38)
  • java跨服务调用接口

    Java程序跨服务调用接口,通常可以使用以下方式: RESTful API:通过HTTP协议进行通信,使用RESTful API调用其他服务的接口。 RPC:使用远程过程调用(RPC)框架,如Dubbo、gRPC等,通过序列化和反序列化技术实现跨服务调用。 消息队列:使用消息队列,如Kafka、RabbitMQ等,服务之间

    2024年02月12日
    浏览(50)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包