Babel AST 入门

什么是AST?AST有什么用?

AST 全称 Abstract Syntax Tree(语法抽象树),简称语法树。
对于爬虫来说,AST 是一种工具,尽可能的处理被混淆的代码,增强其可读性。
本人接触的是 babel ,故往后 AST 相关将默认基于其展开。

准备工作

  1. 一定的 js 基础,本人也是跟着这个教程学的,也时常翻阅(前往教程)
  2. 安装 nodejs 、babel nodejs 官网 babel 官网
    安装 babel 相关工具包时可以全局安装,这样方便调用
    npm install -g --save @babel/traverse

相关文档

必看!反复看!!很重要!!!

实用工具

babel 的处理步骤、思路

babel 的三个主要处理步骤分别是: 解析(parse),转换(transform),生成(generate)。点击查看详情

个人认为,使用 babel 的处理思路其实就是增删改查节点。
譬如

操作节点的核心思想其实就是把你需要处理的代码和你希望处理成的样子放到在线解析网站 AST explorer ,对比差异即可

处理代码时建议一步步将代码拆分,逐个操作,简单易懂

关于处理前后 js 代码节点的不同,参照 @babel/types 即可

AST babel 处理模板

执行命令为:node decrypt.js encode.js decode.js
decrypt.js:babel 处理、解密的 js
encode.js:待处理 js (可以使用绝对路径)
encode.js:处理后 js (可以使用绝对路径)
visitor 中的每个函数接收两个: pathstate(state少用)

// decrypt.js
const fs = require('fs');
var util = require('util');
const parser = require('@babel/parser');
const traverse = require('@babel/traverse').default;
const types = require('@babel/types');
const generator = require('@babel/generator').default;

// 程序启动时间
var time_start = new Date().getTime()
// 读取文件
process.argv.length > 2 ? encode_file = process.argv[2] : encode_file = 'encode.js';
process.argv.length > 3 ? decode_file = process.argv[3] : decode_file = 'decode.js';

let jscode = fs.readFileSync(encode_file, {encoding: 'utf-8'});
// 转换为 ast 树
let ast = parser.parse(jscode);

const visitor =
    {
        // 此处编写 babel 处理代码、插件代码
        ASTNodeTypeHere(path, state) {
        }
        // 如
        // Identifier(path, state) {}
        // Identifier(path) {}
    }

//调用插件,处理待处理 js ast 树
traverse(ast, visitor);
console.log('AST traverse completed.')

// 生成处理后的 js
let {code} = generator(ast);
console.log('AST generator completed.')
fs.writeFile(decode_file, code, (err) => {
});
console.log(util.format('The javascript code in [%s] has been processed.', encode_file))
console.log(util.format('The processing result has been saved to [%s].', decode_file))
// 程序结束时间
var time_end = new Date().getTime()
console.log(util.format('The program runs to completion, time-consuming: %s s', (time_end - time_start) / 1000))

AST Babel demo

AST Babel 实战

推荐阅读

Table of Contents