解析 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">
</td>
<td class="a5">
<a href="/u/695804">
meisam_t72
</a>
</td>
<td class="a6">
<div>
►► زیرنویس از میثم ططری - ویرایش شده ◄◄ - meisam_t72 کانال تلگرام </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">
</td>
<td class="a5">
<a href="/u/546114">
filmb.in
</a>
</td>
<td class="a6">
<div>
filmbin.Cloud | با نسخه HC-HDRip هماهنگ شد </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(不应该)时,我得到一个错误。
我注意到有几件事可能会导致您的代码出现问题。
在您的 foreach 循环中,您正在使用 //
搜索 span[2]。您应该知道 //
会导致搜索查看您的整个代码,而不仅仅是单元格。因此,它将 select Name x 循环执行的次数(在本例中为 5)。
索引的使用在这里似乎不太有效。总是有 x 个跨度,但您将索引基于 tr 的索引,这不太合理。这就是抛出异常的原因
Out of Range Exception.
看来你知道了,但又想重复一遍。 //
将搜索整个文档。如果在循环中,.//
将在您所在的标签下迭代。
以下代码将在 //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());
您好,我正在使用 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">
</td>
<td class="a5">
<a href="/u/695804">
meisam_t72
</a>
</td>
<td class="a6">
<div>
►► زیرنویس از میثم ططری - ویرایش شده ◄◄ - meisam_t72 کانال تلگرام </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">
</td>
<td class="a5">
<a href="/u/546114">
filmb.in
</a>
</td>
<td class="a6">
<div>
filmbin.Cloud | با نسخه HC-HDRip هماهنگ شد </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(不应该)时,我得到一个错误。
我注意到有几件事可能会导致您的代码出现问题。
在您的 foreach 循环中,您正在使用
//
搜索 span[2]。您应该知道//
会导致搜索查看您的整个代码,而不仅仅是单元格。因此,它将 select Name x 循环执行的次数(在本例中为 5)。索引的使用在这里似乎不太有效。总是有 x 个跨度,但您将索引基于 tr 的索引,这不太合理。这就是抛出异常的原因
Out of Range Exception.
看来你知道了,但又想重复一遍。
//
将搜索整个文档。如果在循环中,.//
将在您所在的标签下迭代。以下代码将在 //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());