世界上最稀缺的资源是时间。
在某一瞬间我惊恐得发现,一生三万天,已过三分之一,念及年少不更事,蹉跎而过,觉得心中有愧。至今无建树,脑袋里想起一句话,“不因虚度年华而悔恨,也不因碌碌无为而羞耻”。
如今发起少年狂,对一切都感起兴趣,深知往者不可谏,来着犹可追。空有胸中之宏远,奈何路漫漫其修远,深感无力,只有择一事,写点博客吧!来一点点弥补辜负的少年时光。
准备
安装nodejs,安装fiddler,配置抓取https(后来我想到可以直接用chrome的network抓啊,fiddler抓https主要还是用于手机端)。
nodejs网上教程,很容易安装,fiddle配置https有点复杂,需要字节创建个fiddler证书,网上有教程,本人配置了好久才成功,而且只能抓chrome的https,mozilla浏览器仍然不行 |
用nodejs的原因是本来我已经安装好了,而且node里面用npm下载cropto-js比较方便,这个库可以用来模拟csdn的X-Ca-Signature参数的。X-Ca-Signature用的算法是HmacSHA256。要是能知道原理,也可以通过python直接写出来,关于HmacSHA256也值得另外写篇博客进行研究。不过有现成我就直接拿来用了。
在系统某个地方安装crypto-js,再创建一个js用于模拟X-Ca-Signature,本人创建的路径是D:\nodejsProject\csdn_blog_static
npm install crypto-js
积分接口
登陆CSDN,进入数据观星->博文数据
配置好fiddler的https抓包后(chrome的network也可以),进入数据观星的博客数据,抓包结果如图
一般的网站只需要把报文头复制过来即可模拟登陆状态获取接口数据,但CSDN的报文里面有2个值是随时变化且只能用一次的。X-Ca-Nonce和X-Ca-Signature,因此每次请求接口这2个值需要自己计算。
通过chrome的devtool经过不断关键字匹配,终于匹配到这2个值计算的关键js文件。app.js (估计是业务代码) , chunk_vendors.js (估计是一些库的合并打包)。这2个js是压缩过并且混淆过的,我们可以通过chrome自带的Pretty print让其更容易看,但是混淆过的变量方法名无法恢复复,只能辛苦下。
经过一番debugger,X-Ca-Nonce的生成方法是
X-Ca-Signature的方法是
b方法最终调用
var R = s.a.HmacSHA256(h, a),
S = R.toString(s.a.enc.Base64);
HmacSHA256的参数h是报文头的一部分再加上X-Ca-Nonce,a是appSecret固定值,后期估计会变。经尝试,成功写出相应的js代码:
至此,我们可以开始我们的抓取代码编写。
代码
nodejs
csdn_HmacSHA256.js:
var Crypto = require('crypto-js');
var nonceFunc = function() {
return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (function(e) {
var n = 16 * Math.random() | 0
, t = "x" === e ? n : 3 & n | 8;
return t.toString(16)
}
));
}
var nonce = nonceFunc(), appSecret = "9znpamsyl2c7cdrr9sas0le9vbc3r6ba", h="";
h += "".concat("GET", "\n");
h += "".concat("application/json, text/plain, */*", "\n");
h += "".concat("", "\n");
h += "".concat("", "\n");
h += "".concat("", "\n");
h += "x-ca-key:203803574\n";//目前看来也是固定值
h += "x-ca-nonce:" + nonce + "\n";
h += "/blog-console-api/v1/data/blog_statistics"
var hash = Crypto.HmacSHA256(h, appSecret);
var hashInBase64 = Crypto.enc.Base64.stringify(hash);
console.log(nonce);
console.log(hashInBase64);
python
CsdnKiramario.py:
import urllib.request
import urllib.parse
import os
import gzip
import json
import datetime
from openpyxl import load_workbook
class CsdnKiramario(object):
def __init__(self):
#执行nodejs
output = os.popen('node D:\\nodejsProject\\csdn_blog_static\\csdn_HmacSHA256.js')
#读取nodejs种console输出,不是很严谨
nonce = output.readline()
signature = output.readline()
#报文
targetUrl = 'https://bizapi.csdn.net/blog-console-api/v1/data/blog_statistics'
headers = {
'Host': ' bizapi.csdn.net',
'Connection': 'keep-alive',
'sec-ch-ua': '"Google Chrome";v="89", "Chromium";v="89", ";Not A Brand";v="99"',
'X-Ca-Signature-Headers': 'x-ca-key,x-ca-nonce',
'X-Ca-Signature': signature.strip(),
'X-Ca-Nonce': nonce.strip(),
'sec-ch-ua-mobile': '?0',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.114 Safari/537.36',
'Accept': ' application/json, text/plain, */*',
'X-Ca-Key': ' 203803574',
'Origin': 'https://mp.csdn.net',
'Sec-Fetch-Site': 'same-site',
'Sec-Fetch-Mode': 'cors',
'Sec-Fetch-Dest': 'empty',
'Referer': 'https//mp.csdn.net/console/dataWatch/analysis/allarticle',
'Accept-Encoding': 'gzip, deflate, br',
'Accept-Language': 'zh-CN,zh;q=0.9',
"Cookie": "替换成自己的cookie"
}
self.req = urllib.request.Request(url=targetUrl,method='GET', headers=headers)
def run(self):
res = ""
# 爬取
with urllib.request.urlopen(self.req) as f:
res = f.read()
ret = gzip.decompress(res).decode("utf-8")
ret = json.loads(ret)
data = ret['data']
analysDict = {}
for statistic in data:
name = (statistic['name'])
num = statistic['num']
analysDict[name] = num
# 存入博客xlsx
analysHeader = ["日期", "文章总数", "粉丝数", "点赞数", "评论数", "访问量", "积分", "收藏数", "总排名"]
sourcePath = "D:\\麦芒\\私域计划\\博客\\博客数据.xlsx"
wb = load_workbook(sourcePath)
ws_active = wb['Sheet']
row = []
for headerName in analysHeader:
if headerName == "日期":
row.append(datetime.date.today().strftime("%Y/%m/%d"))
else:
row.append(analysDict[headerName])
ws_active.append(row)
wb.save(sourcePath)
if __name__ == "__main__":
instance = CsdnKiramario()
instance.run()
执行后
更多方法
不想手动执行的话,把python脚本加入windows执行计划,每天执行也可以。
参考博客
https://blog.csdn.net/DylanYuan/article/details/81533105
https://www.cnblogs.com/ruiy/p/6422586.html