惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

F
Full Disclosure
V
Vulnerabilities – Threatpost
Attack and Defense Labs
Attack and Defense Labs
N
News and Events Feed by Topic
SecWiki News
SecWiki News
S
Security @ Cisco Blogs
Schneier on Security
Schneier on Security
B
Blog
TaoSecurity Blog
TaoSecurity Blog
The Last Watchdog
The Last Watchdog
H
Hacker News: Front Page
Hacker News - Newest:
Hacker News - Newest: "LLM"
博客园_首页
D
Docker
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
Y
Y Combinator Blog
W
WeLiveSecurity
N
News and Events Feed by Topic
F
Fortinet All Blogs
PCI Perspectives
PCI Perspectives
WordPress大学
WordPress大学
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
www.infosecurity-magazine.com
www.infosecurity-magazine.com
Recent Announcements
Recent Announcements
Forbes - Security
Forbes - Security
T
Tailwind CSS Blog
Hacker News: Ask HN
Hacker News: Ask HN
爱范儿
爱范儿
腾讯CDC
Last Week in AI
Last Week in AI
月光博客
月光博客
C
Cybersecurity and Infrastructure Security Agency CISA
P
Proofpoint News Feed
Help Net Security
Help Net Security
V
V2EX
C
Cyber Attacks, Cyber Crime and Cyber Security
C
CXSECURITY Database RSS Feed - CXSecurity.com
H
Heimdal Security Blog
L
LINUX DO - 最新话题
GbyAI
GbyAI
The Hacker News
The Hacker News
罗磊的独立博客
S
SegmentFault 最新的问题
H
Hackread – Cybersecurity News, Data Breaches, AI and More
博客园 - 【当耐特】
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
V2EX - 技术
V2EX - 技术
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
O
OpenAI News
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻

梦魇小栈

《羊了个羊》程序员过关攻略 WebRTC 入门指南 将你的博客升级为 PWA 渐进式Web离线应用 Hexo 博客美化代码块 记一下 pm2 常用配置及命令 (译)NPM vs Yarn 备忘手册 用 MySQL 导入 SQL 文件 解决 ubuntu 服务器中文乱码 面试分享:2018阿里巴巴前端面试总结(题目+答案) crontab 踩坑之绝对路径 SED 命令简明教程 在Hexo博客 NexT主题中部署Wildfire评论系统 使用 JavaScript 实现简单的拖拽 Merry Christmas JAVASCRIPT生成图形验证码 笔记:NPM版本号自增,自动化发布NPM包 不可不知的Mac OS X专用命令行工具(持续更新中) 继多说、网易关停之后该何去何从(网易云跟帖宣布2017年8月1日停止服务) 重新介绍 JavaScript(JS全面系列教程)
什么? 微信没有年度账单? 前端 nodejs 撸起来~ [接口实现]
Ihoey 心,若没有栖息的地方,到哪里都是流浪...... · 2019-01-18 · via 梦魇小栈

发表于 | 更新于 | 分类于 Node | 评论数: | 阅读次数:

最近逛掘金看见一片文章 非官方统计 2018 微信年度账单实现,作者利用调试微信获取到了 2018 年的所有消费明细,并根据类型进行分类统计,作文一个前端,便萌生了用 nodejs 实现一遍的想法,于是乎呢,就有了这篇文章了。

由于 @hibear 大佬是用 Java 实现的,并且自己又不会 Java,所以呢里面很多东西确实看不太懂,然后就根据核心代码撸吧。

好了,废话不多说,我们直接开始吧~

首先初始化一个项目吧,按自己的习惯,配置下需要的东西

大概配置完是这些文件

1
2
3
4
5
6
7
8
9
.editorconfig
.gitignore
config.js
init/
package.json
README.md
src/
util/
yarn.lock

然后我们来写个接口;

我们这里选 koa 框架吧,毕竟自己还是蛮喜欢的~

1
2
3
4
5
6
7
// Koa 框架
const Koa = require('koa')
// 实例化
const app = new Koa()
// 监听端口
app.listen(config.port)
console.log(`the server is start at port ${config.port}`)

然后我们来添加路由

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// index.js
const Koa = require('koa')
const KoaRouter = require('koa-router')

const app = new Koa()
// 创建 router 实例对象
const router = new KoaRouter()

//注册路由
router.get('/', async ctx => {
ctx.body = 'welcome~'
})

// 添加路由中间件
app.use(router.routes())

// 对请求进行一些限制处理
app.use(router.allowedMethods())

// 监听启动端口
app.listen(config.port)
console.log(`the server is start at port ${config.port}`)

完整入口文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
// index.js
const Koa = require('koa')
const KoaRouter = require('koa-router')
const bodyParser = require('koa-bodyparser')
const config = require('../config')

const app = new Koa()
// 创建 router 实例对象
const router = new KoaRouter()
// 账单获取核心逻辑
const wechatBill = require('./controllers/wechatBill')

// 配置ctx.body解析中间件
app.use(bodyParser())

//注册路由
router.get('/', async ctx => {
ctx.body = 'welcome~'
})

router.post('/wechatBill', wechatBill)

// 添加路由中间件
app.use(router.routes())

// 对请求进行一些限制处理
app.use(router.allowedMethods())

// 监听启动端口
app.listen(config.port)
console.log(`the server is start at port ${config.port}`)

好了,路由写完了,我们来看核心逻辑怎么写,根据大佬的思路是模拟微信的请求,带上必要的参数就好了,这里我们使用最熟悉的 axios 吧。

由于代码太多这里就贴出核心的部分吧,完整版可以看下 github 的文件,请点击传送门-> 传送门

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
while (Loop) {

if (lastResp.last_create_time < 1514736000) {
wechatList.splice(wechatList.indexOf(wechat_id) >>> 0, 1)
Loop = false
console.log('任务处理完毕,2018全部数据已存入');
}

axios.request({
url: `https://wx.tenpay.com/userroll/userrolllist`,
method: 'get',
headers: {
"Accept": "*/*",
"Accept-Encoding": "gzip, deflate",
"Accept-Language": "zh-CN,en-US;q=0.8",
"Connection": "keep-alive",
"Cookie": `userroll_encryption=${userroll_encryption}; userroll_pass_ticket=${userroll_pass_ticket}`,
"Host": "wx.tenpay.com",
"Q-Auth": AUTH,
"Q-GUID": GUID,
"Q-UA2": UA2,
"Referer": "https://wx.tenpay.com/?classify_type=0",
"User-Agent": "Mozilla/5.0 (Linux; Android 8.0; MIX 2 Build/OPR1.170623.027; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/57.0.2987.132 MQQBrowser/6.2 TBS/044408 Mobile Safari/537.36 MMWEBID/4508 MicroMessenger/7.0.1380(0x27000038) Process/tools NetType/WIFI Language/zh_CN",
"X-DevTools-Emulate-Network-Conditions-Client-Id": ClientId,
"X-Requested-With": "com.tencent.mm",
},
params: {
classify_type: 0,
count: PAGE_SIZE,
exportkey,
last_bill_id: lastResp.last_bill_id,
last_bill_type: lastResp.last_bill_type,
last_create_time: lastResp.last_create_time,
last_trans_id: lastResp.last_trans_id,
sort_type: 1,
start_time: lastResp.start_time,
}

}).then((res) => {

lastResp = res.data

if (!lastResp || lastResp.ret_code != 0 || !lastResp.record) {
console.log(lastResp);
Loop = false
ctx.body = {
code: 2,
res: lastResp.ret_msg || '任务请求失败'
}
throw new Error(`任务请求失败`)
}

ctx.body = {
code: 0,
res: '创建任务成功,正在获取账单中...'
}

const dataList = res.data.record.map(e => ({ wechat_id, ...e }))
dataList.map(async e => {
delete e.coupon
const sql = `INSERT INTO orders(${Object.keys(e)}) VALUES (${JSON.stringify(Object.values(e))})`
const data = await query(sql.replace(/\[|\]/g, ""))
console.log(`存入成功`, data.insertId)
})

}).catch((err) => {
console.log(err)
});
await sleep(1000)
}

好了,具体的代码可以看下 github 的参考~
-> 传送门

满分是10分的话,这篇文章你给几分,您的支持将鼓励我继续创作!