Skip to content

处理不同数据类型(Processing different data types)#

在本章中,你将学习如何使用n8n核心节点处理不同类型的数据。

🌐 In this chapter, you will learn how to process different types of data using n8n core nodes.

HTML 和 XML 数据(HTML and XML data)#

你很可能熟悉 HTML 和 XML。

🌐 You're most likely familiar with HTML and XML.

HTML vs. XML

HTML is a markup language used to describe the structure and semantics of a web page. XML looks similar to HTML, but the tag names are different, as they describe the kind of data they hold.

If you need to process HTML or XML data in your n8n workflows, use the HTML node or the XML node.

使用 HTML 节点 通过引用 CSS 选择器来提取网页的 HTML 内容。如果你想从网站收集结构化信息(网络爬取),这非常有用。

🌐 Use the HTML node to extract HTML content of a webpage by referencing CSS selectors. This is useful if you want to collect structured information from a website (web-scraping).

HTML 练习(HTML Exercise)#

让我们获取 n8n 最新博客文章的标题:

🌐 Let's get the title of the latest n8n blog post:

  1. 使用HTTP 请求节点对 URL https://blog.n8n.io/ 发起 GET 请求(此端点不需要身份验证)。
  2. 连接一个 HTML 节点 并配置它以提取页面上第一个博客文章的标题。
    • 提示:如果你不熟悉 CSS 选择器或阅读 HTML,CSS 选择器 .post .item-title a 应该会有所帮助!

??? 注意 “给我看解决方案”

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
1. 使用以下参数配置 HTTP 请求节点:
    - **认证**:无
    - **请求方法**: GET
    - **网址**: https://blog.n8n.io/ 结果应如下所示:

<figure><img src="/_images/courses/level-two/chapter-two/exercise_html_httprequestnode.png" alt="Result of HTTP Request node" style="width:100%"><figcaption align = "center"><i>HTTP 请求节点的结果</i></figcaption></figure>

2. 将**HTML节点**连接到**HTTP请求节点**,并配置前者的参数:
    - **操作**:提取 HTML 内容
    - **源数据**: JSON
    - **JSON 属性**: data
    - **提取值**:
        - **键**: 标题
        - **CSS选择器**: `.post .item-title  a`
        - **返回值**:HTML

你可以添加更多值以提取更多数据。

结果应该看起来像这样:

<figure><img src="/_images/courses/level-two/chapter-two/exercise_html_htmlextractnode.png" alt="Result of HTML Extract node" style="width:100%"><figcaption align = "center"><i>HTML 提取节点的结果</i></figcaption></figure>

使用 XML 节点 将 XML 转换为 JSON,或将 JSON 转换为 XML。如果你使用的不同 Web 服务分别使用 XML 或 JSON,并且需要在这两种格式之间获取和提交数据,这个操作会很有用。

🌐 Use the XML node to convert XML to JSON and JSON to XML. This operation is useful if you work with different web services that use either XML or JSON and need to get and submit data between them in the two formats.

XML 练习(XML Exercise)#

第1章的最后一个练习中,你使用了一个HTTP 请求节点向 PokéAPI 发起请求。在本次练习中,我们将返回到同一个 API,但会将输出转换为 XML:

🌐 In the final exercise of Chapter 1, you used an HTTP Request node to make a request to the PokéAPI. In this exercise, we'll return to that same API but we'll convert the output to XML:

  1. 添加一个 HTTP 请求节点,对 https://pokeapi.co/api/v2/pokemon 的 PokéAPI 发起相同的请求。
  2. 使用 XML 节点将 JSON 输出转换为 XML。

??? 注意 “给我看解决方案”

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
1. 要从 PokéAPI 获取宝可梦,请使用以下参数执行 **HTTP 请求节点**:
    - **认证**:无
    - **请求方法**: GET
    - **网址**: https://pokeapi.co/api/v2/pokemon
2. 用以下参数将一个 **XML 节点** 连接到它:
    - **模式**:JSON 转 XML
    - **属性名称**: data

结果应该看起来像这样:

<figure><img src="/_images/courses/level-two/chapter-two/exercise_html_xmlnode_table.png" alt="Table view of XML Node (JSON to XML)" style="width:100%"><figcaption align = "center"><i>XML 节点(JSON 转 XML)– 表格视图</i></figcaption></figure>

要将数据反向转换,请选择模式 **XML 转 JSON**。

日期、时间和间隔数据(Date, time, and interval data)#

日期和时间数据类型包括 DATETIMEDATETIMETIMESTAMPYEAR。日期和时间可以以不同的格式传递,例如:

  • DATE:2022年3月29日,2022年3月29日,2022/03/29
  • TIME: 08:30:00,8:30,20:30
  • DATETIME:2022/03/29 08:30:00
  • TIMESTAMP: 1616108400(Unix 时间戳),1616108400000(Unix 毫秒时间戳)
  • YEAR: 2022, 22

有几种处理日期和时间的方法: - 使用 日期和时间节点 将日期和时间数据转换为不同的格式并计算日期。 - 使用 Schedule Trigger 节点 来安排工作流在特定时间、间隔或持续时间运行。

有时,你可能需要暂停工作流的执行。如果你知道某个服务不会立即处理数据,或者返回所有结果的速度很慢,这可能是必要的。在这种情况下,你不希望 n8n 将不完整的数据传递给下一个节点。

🌐 Sometimes, you might need to pause the workflow execution. This might be necessary if you know that a service doesn't process the data instantly or it's slow to return all the results. In these cases, you don't want n8n to pass incomplete data to the next node.

如果你遇到这种情况,可以在你想要延迟的节点之后使用 等待节点等待节点会暂停工作流的执行,并在暂停后继续执行:

🌐 If you run into situations like this, use the Wait node after the node that you want to delay. The Wait node pauses the workflow execution and will resume execution:

  • 在特定时间。
  • 在指定的时间间隔后。
  • Webhook 调用时

日期练习(Date Exercise)#

构建一个工作流,将输入日期(来自之前使用的客户数据存储节点)增加五天。然后,如果计算出的日期在1959年之后,工作流将在将计算日期设置为值之前等待1分钟。该工作流应每30分钟触发一次。

🌐 Build a workflow that adds five days to an input date from the Customer Datastore node that you used before. Then, if the calculated date occurred after 1959, the workflow waits 1 minute before setting the calculated date as a value. The workflow should be triggered every 30 minutes.

开始:

  1. 添加 客户数据存储(n8n 培训)节点 并选择 获取所有人员 操作。返回所有内容。
  2. 添加 日期与时间节点,将数据存储中创建的日期向上舍入到月末。将结果输出到字段 new-date。包括所有输入字段。
  3. 添加If节点来检查新四舍五入的日期是否在 1960-01-01 00:00:00 之后。
  4. 等待节点添加到该节点的 True 输出,并将其设置为等待一分钟。
  5. 添加 编辑字段(集合)节点,设置一个名为 outputValue 的新字段,其类型为字符串,内容为 new-date。包括所有输入字段。
  6. 在工作流的开头添加 计划触发节点,每30分钟触发一次。(你可以保留 手动触发节点 用于测试!)

??? 注意 “给我看解决方案”

  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
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
1. 添加 **客户数据存储(n8n 培训)节点**,并选择 **获取所有人员** 操作。
    - 选择选项 **全部返回**。
2. 添加一个连接到客户数据存储节点的**日期和时间节点**。选择**四舍五入日期**选项。
    - 将 `created` 日期作为要汇总的**日期**添加。
    - 选择 `Round Up` 作为 **模式**,选择 `End of Month` 作为 **目标**。
    - 将**输出字段名称**设置为 `new-date`。
    - 在**选项**中,选择**添加选项**,并使用控件**包含输入字段**
3. 添加一个 **If 节点** 并连接到 **日期与时间节点**。
    - 将 new-date 字段作为条件的第一部分添加。
    - 将比较设置为 **日期和时间 > 晚于**
    - 将 `1960-01-01 00:00:00` 添加为表达式的第二部分。(这应该会在真分支中产生 3 个项目,在假分支中产生 2 个项目)
4. 在 **If 节点** 的 True 输出端添加一个 **Wait 节点**。
    - 将 **Resume** 设置为 `After Time interval`。
    - 将 **等待金额** 设置为 `1.00`。
    - 将 **Wait Unit** 设置为 `Minutes`。
5. 在 **等待节点** 上添加一个 **编辑字段(设置)节点**。
    - 使用 JSON 或手动映射 **模式**。
    - 将一个名为 `outputValue` 的新字段设置为 new-date 字段的值。
    - 选择选项 **包括其他输入字段** 并包含 **所有** 字段。
6. 在工作流的开头添加一个 **计划触发节点**。
    - 将**触发间隔**设置为使用`Minutes`。
    - 将 **触发间隔分钟数** 设置为 30。
    - 要测试你的日程安排,请确保发布工作流。
    - 请确保将此节点连接到你最初创建的**Customer Datastore (n8n training) 节点**!

工作流应如下所示:

<figure><img src="/_images/courses/level-two/chapter-two/exercise_datetime.png" alt="Workflow for transforming dates" style="width:100%"><figcaption align = "center"><i>日期转换工作流程</i></figcaption></figure>

要检查每个节点的配置,你可以复制此工作流的 JSON 代码,然后将其粘贴到编辑器 UI 中,或者保存为文件并从文件导入到新的工作流中。有关更多信息,请参见[导出和导入工作流](/workflows/export-import.md)。

```json
{
"name": "Course 2, Ch 2, Date exercise",
"nodes": [
    {
    "parameters": {},
    "id": "6bf64d5c-4b00-43cf-8439-3cbf5e5f203b",
    "name": "When clicking \"Execute workflow\"",
    "type": "n8n-nodes-base.manualTrigger",
    "typeVersion": 1,
    "position": [
        620,
        280
    ]
    },
    {
    "parameters": {
        "operation": "getAllPeople",
        "returnAll": true
    },
    "id": "a08a8157-99ee-4d50-8fe4-b6d7e16e858e",
    "name": "Customer Datastore (n8n training)",
    "type": "n8n-nodes-base.n8nTrainingCustomerDatastore",
    "typeVersion": 1,
    "position": [
        840,
        360
    ]
    },
    {
    "parameters": {
        "operation": "roundDate",
        "date": "={{ $json.created }}",
        "mode": "roundUp",
        "outputFieldName": "new-date",
        "options": {
        "includeInputFields": true
        }
    },
    "id": "f66a4356-2584-44b6-a4e9-1e3b5de53e71",
    "name": "Date & Time",
    "type": "n8n-nodes-base.dateTime",
    "typeVersion": 2,
    "position": [
        1080,
        360
    ]
    },
    {
    "parameters": {
        "conditions": {
        "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict"
        },
        "conditions": [
            {
            "id": "7c82823a-e603-4166-8866-493f643ba354",
            "leftValue": "={{ $json['new-date'] }}",
            "rightValue": "1960-01-01T00:00:00",
            "operator": {
                "type": "dateTime",
                "operation": "after"
            }
            }
        ],
        "combinator": "and"
        },
        "options": {}
    },
    "id": "cea39877-6183-4ea0-9400-e80523636912",
    "name": "If",
    "type": "n8n-nodes-base.if",
    "typeVersion": 2,
    "position": [
        1280,
        360
    ]
    },
    {
    "parameters": {
        "amount": 1,
        "unit": "minutes"
    },
    "id": "5aa860b7-c73c-4df0-ad63-215850166f13",
    "name": "Wait",
    "type": "n8n-nodes-base.wait",
    "typeVersion": 1.1,
    "position": [
        1480,
        260
    ],
    "webhookId": "be78732e-787d-463e-9210-2c7e8239761e"
    },
    {
    "parameters": {
        "assignments": {
        "assignments": [
            {
            "id": "e058832a-2461-4c6d-b584-043ecc036427",
            "name": "outputValue",
            "value": "={{ $json['new-date'] }}",
            "type": "string"
            }
        ]
        },
        "includeOtherFields": true,
        "options": {}
    },
    "id": "be034e9e-3cf1-4264-9d15-b6760ce28f91",
    "name": "Edit Fields",
    "type": "n8n-nodes-base.set",
    "typeVersion": 3.3,
    "position": [
        1700,
        260
    ]
    },
    {
    "parameters": {
        "rule": {
        "interval": [
            {
            "field": "minutes",
            "minutesInterval": 30
            }
        ]
        }
    },
    "id": "6e8e4308-d0e0-4d0d-bc29-5131b57cf061",
    "name": "Schedule Trigger",
    "type": "n8n-nodes-base.scheduleTrigger",
    "typeVersion": 1.1,
    "position": [
        620,
        480
    ]
    }
],
"pinData": {},
"connections": {
    "When clicking \"Execute workflow\"": {
    "main": [
        [
        {
            "node": "Customer Datastore (n8n training)",
            "type": "main",
            "index": 0
        }
        ]
    ]
    },
    "Customer Datastore (n8n training)": {
    "main": [
        [
        {
            "node": "Date & Time",
            "type": "main",
            "index": 0
        }
        ]
    ]
    },
    "Date & Time": {
    "main": [
        [
        {
            "node": "If",
            "type": "main",
            "index": 0
        }
        ]
    ]
    },
    "If": {
    "main": [
        [
        {
            "node": "Wait",
            "type": "main",
            "index": 0
        }
        ]
    ]
    },
    "Wait": {
    "main": [
        [
        {
            "node": "Edit Fields",
            "type": "main",
            "index": 0
        }
        ]
    ]
    },
    "Schedule Trigger": {
    "main": [
        [
        {
            "node": "Customer Datastore (n8n training)",
            "type": "main",
            "index": 0
        }
        ]
    ]
    }
}
}
```

二进制数据(Binary data)#

到目前为止,你主要处理的是文本数据。但如果你想处理非文本的数据,比如图片或PDF文件呢?这些类型的文件是用二进制数表示的,所以被认为是二进制数据。在这种形式下,二进制数据并不能提供有用的信息,因此你需要将其转换为可读的形式。

🌐 Up to now, you have mainly worked with text data. But what if you want to process data that's not text, like images or PDF files? These types of files are represented in the binary numeral system, so they're considered binary data. In this form, binary data doesn't offer you useful information, so you'll need to convert it into a readable form.

在 n8n 中,你可以使用以下节点处理二进制数据:

🌐 In n8n, you can process binary data with the following nodes:

读取和写入文件仅适用于自托管的 n8n

在 n8n Cloud 上无法进行文件的读写操作。你将会在安装了 n8n 的机器上进行读写。如果你在 Docker 中运行 n8n,你的命令将在 n8n 容器中运行,而不是 Docker 主机上。‘从磁盘读取/写入文件’节点会在相对于 n8n 安装路径的地方查找文件。n8n 建议使用绝对文件路径以防止任何错误。

要读取或写入二进制文件,你需要在节点的 File(s) Selector 参数中写入文件的路径(用于读取操作),或在节点的 File Path and Name 参数中写入文件的路径(用于写入操作)。

🌐 To read or write a binary file, you need to write the path (location) of the file in the node's File(s) Selector parameter (for the Read operation) or in the node's File Path and Name parameter (for the Write operation).

命名正确的路径

文件路径根据你运行 n8n 的方式会略有不同:

  • npm: ~/my_file.json
  • n8n cloud / Docker: /tmp/my_file.json

二进制练习 1(Binary Exercise 1)#

第一个二进制练习,我们将把 PDF 文件转换为 JSON:

🌐 For our first binary exercise, let's convert a PDF file to JSON:

  1. 发送 HTTP 请求以获取此 PDF 文件:https://media.kaspersky.com/pdf/Kaspersky_Lab_Whitepaper_Anti_blocker.pdf.
  2. 使用 从文件提取节点 将文件从二进制转换为 JSON。

??? 注意 “给我看解决方案”

 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
71
72
73
74
75
76
77
78
79
80
81
在 **HTTP 请求节点** 中,你应该可以看到 PDF 文件,如下所示:

<figure><img src="/_images/courses/level-two/chapter-two/exercise_binarydata_httprequest_file.png" alt="HTTP Request node to get PDF" style="width:100%"><figcaption align = "center"><i>HTTP 请求节点获取 PDF</i></figcaption></figure>

当你使用**从文件提取节点**将 PDF 从二进制转换为 JSON 时,结果应如下所示:

<figure><img src="/_images/courses/level-two/chapter-two/exercise_binarydata_movedata_btoj.png" alt="Extract From File node" style="width:100%"><figcaption align = "center"><i>从文件节点提取</i></figcaption></figure>

要检查节点的配置,你可以将下面的 JSON 工作流代码复制并粘贴到你的编辑器界面中:

```json
{
    "name": "Binary to JSON",
    "nodes": [
        {
        "parameters": {},
        "id": "78639a25-b69a-4b9c-84e0-69e045bed1a3",
        "name": "When clicking \"Execute Workflow\"",
        "type": "n8n-nodes-base.manualTrigger",
        "typeVersion": 1,
        "position": [
            480,
            520
        ]
        },
        {
        "parameters": {
            "url": "https://media.kaspersky.com/pdf/Kaspersky_Lab_Whitepaper_Anti_blocker.pdf",
            "options": {}
        },
        "id": "a11310df-1287-4e9a-b993-baa6bd4265a6",
        "name": "HTTP Request",
        "type": "n8n-nodes-base.httpRequest",
        "typeVersion": 4.1,
        "position": [
            700,
            520
        ]
        },
        {
        "parameters": {
            "operation": "pdf",
            "options": {}
        },
        "id": "88697b6b-fb02-4c3d-a715-750d60413e9f",
        "name": "Extract From File",
        "type": "n8n-nodes-base.extractFromFile",
        "typeVersion": 1,
        "position": [
            920,
            520
        ]
        }
    ],
    "pinData": {},
    "connections": {
        "When clicking \"Execute Workflow\"": {
        "main": [
            [
            {
                "node": "HTTP Request",
                "type": "main",
                "index": 0
            }
            ]
        ]
        },
        "HTTP Request": {
        "main": [
            [
            {
                "node": "Extract From File",
                "type": "main",
                "index": 0
            }
            ]
        ]
        }
    }
}
```

二进制练习 2(Binary Exercise 2)#

第二个二进制练习,我们将把一些 JSON 数据转换为二进制:

🌐 For our second binary exercise, let's convert some JSON data to binary:

  1. 向 Poetry DB API https://poetrydb.org/random/1 发起 HTTP 请求。
  2. 使用 转换为文件节点 将返回的数据从 JSON 转换为二进制。
  3. 使用 从磁盘读取/写入文件节点 将新的二进制文件数据写入运行 n8n 的机器。
  4. 要检查是否成功,可以使用 从磁盘读/写文件节点 来读取生成的二进制文件。

??? 注意 “给我看解决方案”

  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
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
这个练习的工作流程如下:

<figure><img src="/_images/courses/level-two/chapter-two/exercise_binarydata.png" alt="Workflow for moving JSON to binary data" style="width:100%"><figcaption align = "center"><i>将 JSON 转换为二进制数据的工作流程</i></figcaption></figure>

要检查节点的配置,你可以将下面的 JSON 工作流代码复制并粘贴到你的编辑器界面中:

```json
{
    "name": "JSON to file and Read-Write",
    "nodes": [
        {
        "parameters": {},
        "id": "78639a25-b69a-4b9c-84e0-69e045bed1a3",
        "name": "When clicking \"Execute Workflow\"",
        "type": "n8n-nodes-base.manualTrigger",
        "typeVersion": 1,
        "position": [
            480,
            520
        ]
        },
        {
        "parameters": {
            "url": "https://poetrydb.org/random/1",
            "options": {}
        },
        "id": "a11310df-1287-4e9a-b993-baa6bd4265a6",
        "name": "HTTP Request",
        "type": "n8n-nodes-base.httpRequest",
        "typeVersion": 4.1,
        "position": [
            680,
            520
        ]
        },
        {
        "parameters": {
            "operation": "toJson",
            "options": {}
        },
        "id": "06be18f6-f193-48e2-a8d9-35f4779d8324",
        "name": "Convert to File",
        "type": "n8n-nodes-base.convertToFile",
        "typeVersion": 1,
        "position": [
            880,
            520
        ]
        },
        {
        "parameters": {
            "operation": "write",
            "fileName": "/tmp/poetrydb.json",
            "options": {}
        },
        "id": "f2048e5d-fa8f-4708-b15a-d07de359f2e5",
        "name": "Read/Write Files from Disk",
        "type": "n8n-nodes-base.readWriteFile",
        "typeVersion": 1,
        "position": [
            1080,
            520
        ]
        },
        {
        "parameters": {
            "fileSelector": "={{ $json.fileName }}",
            "options": {}
        },
        "id": "d630906c-09d4-49f4-ba14-416c0f4de1c8",
        "name": "Read/Write Files from Disk1",
        "type": "n8n-nodes-base.readWriteFile",
        "typeVersion": 1,
        "position": [
            1280,
            520
        ]
        }
    ],
    "pinData": {},
    "connections": {
        "When clicking \"Execute Workflow\"": {
        "main": [
            [
            {
                "node": "HTTP Request",
                "type": "main",
                "index": 0
            }
            ]
        ]
        },
        "HTTP Request": {
        "main": [
            [
            {
                "node": "Convert to File",
                "type": "main",
                "index": 0
            }
            ]
        ]
        },
        "Convert to File": {
        "main": [
            [
            {
                "node": "Read/Write Files from Disk",
                "type": "main",
                "index": 0
            }
            ]
        ]
        },
        "Read/Write Files from Disk": {
        "main": [
            [
            {
                "node": "Read/Write Files from Disk1",
                "type": "main",
                "index": 0
            }
            ]
        ]
        }
    }
}
```