前言

爬虫程序(Python、Go 编写)如何解析 SSR 页面内嵌的数据,多是 JavaScript 对象且无法正常转换成 JSON 格式。如:

1
2
3
4
5
6
7
8
9
<script type="tyus-text/javascript">
{
// ...

const data = [{"type":"data","data":{user:null},"uses":{}},{"type":"data","data":{product:{id:"tyu67",name:"Title",icon_url:"images/icon.webp",website_image_url:"images/banner.webp",url:"https://example.com/",description:"Lorem...",meta:{what:"Loras sfjt."},subcategory:[],categories:{id:12345,name:"Cate1"}}},"uses":{"params":["slug"]}}];

// ...
}
</script>

这是份最小化的示例代码,代码中直接把 JavaScript 数组赋值给 data 常量。在经过数据清洗拿到这串数组(实际上是字符串)后进行反序列化会报错,最明显的就是这串字符串中的键值对中的键名没有双引号括起来,导致反序列化失败。

Python 解决方案

1
2
3
4
5
import demjson3

demjson3.encode(['one', 42, True, None]) # 从 Python 转到 JSON

demjson3.decode('["one", 42, true, null]') # 从 JSON 转到 Python

Go 解决方案

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package main

import (
"fmt"
"gopkg.in/yaml.v2"
)

func main() {
blob := []byte(`{license_type: "perpetual", is_trial: true}`)
type License struct {
LicenseType string `yaml:"license_type,omitempty"`
IsTrial bool `yaml:"is_trial,omitempty"`
}
var license License
if err := yaml.Unmarshal(blob, &license); err != nil {
fmt.Println("error: ", err)
} else {
fmt.Printf("%+v", license)
}
}