> For the complete documentation index, see [llms.txt](https://developers.oxylabs.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://developers.oxylabs.io/products/cn/web-scraper-api/features/custom-parser/writing-instructions-manually/parsing-instruction-examples.md).

# 解析指令示例

以下 HTML 片段使用后续章节中的示例解析指令进行解析。

### 示例 HTML <a href="#sample-html" id="sample-html"></a>

```html
<body>
    <div id="products">
        <div class="product" id="shoes">
            <div class="title">Shoes</div>
            <div class="price">223.12</div>
            <div class="description">
                <ul>
                    <li class="description-item">Super</li>
                </ul>
            </div>
        </div>
        <div class="product" id="pants">
            <div class="title">Pants</div>
            <div class="price">60.12</div>
            <div class="description">
                <ul>
                    <li class="description-item">Amazing</li>
                    <li class="description-item">Quality</li>
                </ul>
            </div>
        </div>
        <div class="product" id="socks">
            <div class="title">袜子</div>
            <div class="price">123.12</div>
            <div class="description">
                <ul>
                    <li class="description-item">非常</li>
                    <li class="description-item">不错</li>
                    <li class="description-item">袜子</li>
                </ul>
            </div>
        </div>
    </div>
</body>
```

### 最低限度 <a href="#bare-minimum" id="bare-minimum"></a>

{% hint style="info" %}
用例：你想从所有 **鞋子** **描述** **项目**.
{% endhint %}

*示例 1. 使用 XPath 选择鞋子的描述项目。*

```json
{
    "shoes_description": {
        "_fns": [
            {
                "_fn": "xpath",
                "_args": [
                    ".//div[@id='shoes']//li[@class='description-item']/text()"
                ]
            }
        ]
    }
}
```

该 `xpath` 函数会找到单个项目，并以字符串形式将其放入列表中：

```json
{
    "shoes_description": [
        "Super"
    ]
}
```

精确的 `xpath` 函数行为已说明 [**这里**](/products/cn/web-scraper-api/features/custom-parser/writing-instructions-manually/list-of-functions.md).

### 嵌套解析指令 <a href="#nested-parsing-instructions" id="nested-parsing-instructions"></a>

{% hint style="info" %}
用例：你想解析与鞋子相关的所有信息。此外，解析结果应表示所提供 HTML 的文档结构。
{% endhint %}

你要定位示例 HTML 的这一部分：

```html
<div class="product" id="shoes">
    <div class="title">Shoes</div>
    <div class="price">223.12</div>
    <div class="description">
        <ul>
            <li class="description-item">Super</li>
        </ul>
    </div>
</div>
```

并且你希望解析结果具有以下结构：

```json
{
    "shoes": {
        "title": "Shoes",
        "price": "223.12",
        "description": [
            "Super"
        ]
    }
}
```

解析指令如下。

*示例 2. 解析指令用于解析* `鞋子` *信息。*

```json
{
    "shoes": {
        "title": {
            "_fns": [
                {
                    "_fn": "xpath_one",
                    "_args": ["//div[@id='shoes']/div[@class='title']/text()"]
                }
            ]
        },
        "price": {
            "_fns": [
                {
                    "_fn": "xpath_one",
                    "_args": ["//div[@id='shoes']/div[@class='price']/text()"]
                }
            ]
        },
        "description": {
            "_fns": [
                {
                    "_fn": "xpath",
                    "_args": ["//div[@id='shoes']//li[@class='description-item']/text()"]
                }
            ]
        }
    }
}
```

`xpath_one` 的工作方式类似于 `xpath`，但它不会返回所有匹配项的列表，而是 **返回第一个匹配项**.

在上面的示例中， `鞋子` 属性是最外层指令作用域中定义的唯一属性。 `鞋子` 属性包含嵌套解析指令。

该 `鞋子` 指令作用域没有定义管道（`_fns` 属性缺失）。 `title`, `price`、以及 `描述` 作用域将使用待解析文档作为管道输入。

在示例 2 中，你可以看到以下内容的重复： `//div[@id='shoes']` 在 XPath 表达式中。通过在以下位置定义管道，可以避免这种重复： `鞋子` 作用域：

*示例 3. 在以下位置定义管道：* `鞋子` *作用域指令，以避免 XPath 表达式重复。*

```json
{
    "shoes": {
        "_fns": [
            {
                "_fn": "xpath_one",
                "_args": ["//div[@id='shoes']"]
            }
        ],
        "title": {
            "_fns": [
                {
                    "_fn": "xpath_one",
                    "_args": ["./div[@class='title']/text()"]
                }
            ]
        },
        "price": {
            "_fns": [
                {
                    "_fn": "xpath_one",
                    "_args": ["./div[@class='price']/text()"]
                }
            ]
        },
        "description": {
            "_fns": [
                {
                    "_fn": "xpath",
                    "_args": [".//li[@class='description-item']/text()"]
                }
            ]
        }
    }
}
```

通过使用示例 3 中提供的解析指令，自定义解析器将：

1. 首先处理 `shoes._fns` 管道，它将输出 `鞋子` HTML 元素；
2. 取 `shoes._fns` 管道输出，并将其用作在以下位置定义的管道的输入： `title`, `price`、以及 `描述` 作用域；
3. 处理 `title`, `price`、以及 `描述` 管道以生成最终值。

结果将与示例 2 的结果相同：

```json
{
    "shoes": {
        "title": "Shoes",
        "price": "223.12",
        "description": [
            "Super"
        ]
    }
}
```

示例 2 和示例 3 的主要区别在于，在示例 3 中，管道定义在 `鞋子` 作用域中。 **这个附加管道会选择鞋子的元素，并将其传递给指令层级更深处的其他管道。**

### 嵌套对象列表 <a href="#list-of-nested-objects" id="list-of-nested-objects"></a>

{% hint style="info" %}
**用例：** 之前，你只想解析 `鞋子` 信息。现在你想解析 HTML 中所有产品的信息。
{% endhint %}

该 [**示例 HTML**](#sample-html) 再次用作待解析文档。

如果你希望解析结果如下所示：

```json
{
    "products": [
        {
            "title": "Shoes",
            "price": "223.12",
            "description": [
                "Super"
            ]
        },
        {
            "title": "Pants",
            "price": "60.12",
            "description": [
                "Amazing",
                "Quality"
            ]
        },
        {
            "title": "Socks",
            "price": "123.12",
            "description": [
                "Very",
                "Nice",
                "Socks"
            ]
        }
    ]
}
```

解析指令如下：

*示例 4. 解析 HTML 文档中找到的所有产品。*

```json
{
    "products": {
        "_fns": [
            {
                "_fn": "xpath",
                "_args": ["//div[@class='product']"]
            }
        ],
        "_items": {
            "title": {
                "_fns": [
                    {
                        "_fn": "xpath_one",
                        "_args": ["./div[@class='title']/text()"]
                    }
                ]
            },
            "price": {
                "_fns": [
                    {
                        "_fn": "xpath_one",
                        "_args": ["./div[@class='price']/text()"]
                    }
                ]
            },
            "description": {
                "_fns": [
                    {
                        "_fn": "xpath",
                        "_args": [".//li[@class='description-item']/text()"]
                    }
                ]
            }
        }
    }
}
```

解析指令结构与示例 3 中的类似。不过，有两个主要例外：

1. `xpath` 使用的是，而不是 `xpath_one` 位于 `products._fns` 管道。 `products._fns` 管道现在将输出与所提供 XPath 表达式匹配的所有元素列表（产品元素列表）。
2. `_items` 保留属性用于表示你要通过遍历以下内容的每一项来形成列表： `products._fns` 管道输出，并 **单独传递/处理每个列表项** 在管道作用域中向下传递。

如果 `_items` 在示例 4 的解析指令中如果未使用保留属性，则解析结果如下：

```json
{
    "products": {
        "title": [
            "Shoes",
            "Pants",
            "Socks"
        ],
        "price": [
            "223.12",
            "60.12",
            "123.12"
        ],
        "description": [
            [
                "Super"
            ],
            [
                "Amazing",
                "Quality"
            ],
            [
                "Very",
                "Nice",
                "Socks"
            ]
        ]
    }
}
```

{% hint style="warning" %}
`_items` 用于指定自定义解析器必须传递 ***单独的列表项*** 而不是 ***整个列表*** 到解析指令中。
{% endhint %}

### 从列表中选择第 N 个元素 <a href="#select-n-th-element-from-a-list" id="select-n-th-element-from-a-list"></a>

本节展示管道的灵活性。同一问题可以用不同方式处理。

可以使用多种方式从任意值列表中选择第 N 个元素。

{% hint style="info" %}
**用例：** 你想从页面中选择第二个产品价格。
{% endhint %}

该 [**示例 HTML**](#sample-html) 再次用作示例。你有多种方式选择第 2 个产品。

#### 选项 1 <a href="#option-1" id="option-1"></a>

你可以使用 XPath `[]` 选择器，并在 XPath 表达式中定义选择。

*示例 5. 使用 XPath \[] 选择器选择第 2 个价格。*

```json
{
    "second_price": {
        "_fns": [
            {
                "_fn": "xpath",
                "_args": [
                    "(//div[@class='price'])[2]/text()"
                ]
            }
        ]
    }
}
```

结果：

```json
{
    "second_price": [
        "60.12"
    ]
}
```

#### 选项 2 <a href="#option-2" id="option-2"></a>

你还可以使用 `xpath` 函数查找所有价格，并将其通过管道传递给函数 `select_nth`，该函数会从提取出的价格列表中选择第 n 个元素。

*示例 6. 使用 \`select\_nth\` 函数选择第 2 个值。*

```json
{
    "second_price": {
        "_fns": [
            {
                "_fn": "xpath",
                "_args": [
                    "//div[@class='price']/text()"
                ]
            },
            {
                "_fn": "select_nth",
                "_args": 1
            }
        ]
    }
}
```

结果：

```json
{
    "second_price": "60.12"
}
```

{% hint style="warning" %}
注意 `select_nth` 函数从列表中返回单个项，而 `xpath` 函数返回的是项目列表，即使只找到一个项目。
{% endhint %}

#### 选项 3 <a href="#option-3" id="option-3"></a>

你可以使用 `select_nth` 与任何列表类型一起使用，包括 HTML 元素列表：

*示例 7. 使用以下条件选择所有产品 HTML 元素：* `class="product"` *==> 从列表中选择第 2 个产品元素 ==> 从所选产品 HTML 元素中提取价格文本*.

```json
{
    "second_price": {
        "_fns": [
            {
                "_fn": "xpath",
                "_args": ["//div[@class='product']"]
            },
            {
                "_fn": "select_nth",
                "_args": 1
            },
            {
                "_fn": "xpath",
                "_args": ["./div[@class='price']/text()"]
            }
        ]
    }
}
```

结果：

```json
{
    "second_price": ["60.12"]
}
```

### 错误处理 <a href="#error-handling" id="error-handling"></a>

给定以下 HTML 片段时：

```html
<div class="product" id="shoes">
    <div class="title">Nice Shoes</div>
    <div class="price">223.12</div>
    <div class="description">Super</div>
</div>
```

并尝试使用以下解析指令解析它：

```json
{
    "product": {
        "_fns": [
            {
                "_fn": "xpath_one",
                "_args": ["//div[@id='shoes']"]
            }
        ],
        "price": {
            "_fns": [
                {
                    "_fn": "xpath_one",
                    "_args": ["//div[@class='price']/text()"]
                }
            ]
        },
        "title": {
            "_fns": [
                {
                    "_fn": "xpath_one",
                    "_args": ["//div[@class='title']/text()"]
                }
            ]
        },
        "description": {
            "_fns": [
                {
                    "_fn": "xpath_one",
                    "_args": ["//div[@class='description']/text()"]
                },
                {
                    "_fn": "convert_to_float"
                }
            ]
        }
    }
}
```

自定义解析器将返回一个解析结果，其中 `price` 和 `title` 已正常解析，但 `描述` 由于以下原因解析失败： `convert_to_float` 函数无法转换 `字符串` 到 `浮点数`:

```json
{
    "product": {
        "price": "223.12",
        "title": "Shoes",
        "description": null
    },
    "_warnings": [
        {
            "_fn": "convert_to_float",
            "_fn_idx": 1,
            "_msg": "Failed to process function.",
            "_path": ".product.description"
        }
    ]
}
```

默认情况下，所有错误都会计为警告，并放入 `_warnings` 列表中。如果你想在解析字段时忽略错误，可以使用以下设置抑制警告/错误： `"_on_error": "suppress"` 参数：

```json
{
    "product": {
        ...,
        "description": {
            "_on_error": "suppress",
            "_fns": [
                {
                    "_fn": "xpath_one",
                    "_args": ["//div[@class='description']/text()"]
                },
                {
                    "_fn": "convert_to_float"
                }
            ]
        }
    }
}
```

然后会产生如下结果：

```json
{
    "product": {
        "price": "223.12",
        "title": "Shoes",
        "description": null
    }
}
```

### 数组的数组 <a href="#array-of-arrays" id="array-of-arrays"></a>

自定义解析器允许在解析结果中使用 N 维数组。例如，我们使用以下 HTML 片段：

```html
<div class="row">
    <div class="column">1</div>
    <div class="column">2</div>
    <div class="column">3</div>
</div>
<div class="row">
    <div class="column">4</div>
    <div class="column">5</div>
    <div class="column">6</div>
</div>
<div class="row">
    <div class="column">7</div>
    <div class="column">8</div>
    <div class="column">9</div>
</div>
```

假设你想解析文档，使结果成为一个 3x3 的二维整数数组：

```json
{
    "table": [
        [1, 2, 3],
        [4, 5, 6],
        [7, 8, 9],
    ]
}
```

要将 HTML 解析为上面的 JSON，可以使用以下解析指令：

```json
{
    "table": {
        "_fns": [
            {
                "_fn": "xpath",
                "_args": ["//div[@class='row']"]
            },
            {
                "_fn": "xpath",
                "_args": [".//div[@class='column']/text()"]
            },
            {
                "_fn": "convert_to_int"
            }
        ]
    }
}
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://developers.oxylabs.io/products/cn/web-scraper-api/features/custom-parser/writing-instructions-manually/parsing-instruction-examples.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
