解析 html 并选择第一个 table 和第二个跨度

parsing html and selecting first table with second span

您好,我正在使用 htmlagilitypack 解析 html 页面我的应用程序之前运行良好,但最近由于 html 页面更改而出现问题。

问题是我正在解析一个特定的 table(第一个 table),但在解析它并给出一个 ArgumentOutOfRangeException 错误之后它看起来像是要转到另一个 table =14=]

这是html内容

<table>
<tbody>
<tr>
<td class="a1">
<a href="/subtitles/joker-2019/farsi_persian/2110062">
<span class="l r positive-icon">
Farsi/Persian
</span>
<span>
Joker.2019.WEBRip.XviD.MP3-SHITBOX
</span>
</a>
</td>
<td class="a3">
</td>
<td class="a40">
&nbsp;
</td>
<td class="a5">
<a href="/u/695804">
meisam_t72
</a>
</td>
<td class="a6">
<div>
►► زیرنویس از میثم ططری - ویرایش شده ◄◄ - meisam_t72 کانال تلگرام&nbsp; </div>
</td>
</tr>
</tbody>
</table>

<table>
<tr>
<td class="a1">
<a href="/subtitles/joker-2019/farsi_persian/2087508">
<span class="l r bad-icon">
Farsi/Persian
</span>
<span>
Joker.2019.1080p.HC.HDRip.1400MB.DD2.0.x264-GalaxyRG
</span>
</a>
</td>
<td class="a3">
</td>
<td class="a40">
&nbsp;
</td>
<td class="a5">
<a href="/u/546114">
filmb.in
</a>
</td>
<td class="a6">
<div>
filmbin.Cloud | با نسخه HC-HDRip هماهنگ شد&nbsp; </div>
</td>
</tr>
</table>

这就是页面解析的方式

HtmlDocument doc = await web.LoadFromWebAsync(url);
HtmlNode table = doc.DocumentNode.SelectSingleNode("//table[1]//tbody");
if (table != null)
                {
                    foreach ((HtmlNode cell, int index) in table.SelectNodes(".//tr/td").WithIndex())
                    {
                       // i get error in this line
                       string Name = cell.SelectNodes("//span[2]")[index].InnerText;
                    }
                }

关键是首先第一个 table 中的所有项目都被很好地解析,当我输入第二个 table(不应该)时,我得到一个错误。

我注意到有几件事可能会导致您的代码出现问题。

  1. 在您的 foreach 循环中,您正在使用 // 搜索 span[2]。您应该知道 // 会导致搜索查看您的整个代码,而不仅仅是单元格。因此,它将 select Name x 循环执行的次数(在本例中为 5)。

  2. 索引的使用在这里似乎不太有效。总是有 x 个跨度,但您将索引基于 tr 的索引,这不太合理。这就是抛出异常的原因

    Out of Range Exception.

  3. 看来你知道了,但又想重复一遍。 // 将搜索整个文档。如果在循环中,.// 将在您所在的标签下迭代。

  4. 以下代码将在 //table/tbody 中生成您要查找的输出。 //table/tr 下的任何内容都将被忽略,因为 tr 在 tbody 下是 "not"。您示例中的第二个 table 将被忽略。

    HtmlNode table = doc.DocumentNode.SelectSingleNode("//table//tbody");
    if (table != null)
    {
        foreach (HtmlNode cell in table.SelectNodes(".//tr/td"))
        {
            var nodeWithSpanTag = cell.SelectSingleNode(".//span[2]");
            if (nodeWithSpanTag != null)
                Console.WriteLine(nodeWithSpanTag.InnerText.Trim());
        }
    }

输出

    Joker.2019.WEBRip.XviD.MP3-SHITBOX

如果我使用 //span(而不是 .//span),我将上面的行打印 5 次。

此示例将产生与上面相同的结果,

 Console.WriteLine(doc.DocumentNode.SelectSingleNode("//table//tbody//tr/td//span[2]")?.InnerText.Trim());