我正在尝试为 Digikey 编写一个屏幕抓取工具,这将使我们公司能够在零件停产时准确跟踪定价、零件可用性和产品更换。 我在 Chrome Devtools 以及 Firefox 上的 Firebug 中看到的 XPATH 与我的 C# 程序中看到的似乎存在差异。
我当前正在抓取的页面是 http://search.digikey.com/scripts/DkSearch/dksus.dll?Detail&name=296-12602-1-ND
我当前使用的代码非常快速且肮脏......
//This function retrieves data from the digikey
private static List<string> ExtractProductInfo(HtmlDocument doc)
{
List<HtmlNode> m_unparsedProductInfoNodes = new List<HtmlNode>();
List<string> m_unparsedProductInfo = new List<string>();
//Base Node for part info
string m_baseNode = @"//html[1]/body[1]/div[2]";
//Write part info to list
m_unparsedProductInfoNodes.Add(doc.DocumentNode.SelectSingleNode(m_baseNode + @"/table[1]/tr[1]/td[1]/table[1]/tr[1]/td[1]"));
//More lines of similar form will go here for more info
//this retrieves digikey PN
foreach(HtmlNode node in m_unparsedProductInfoNodes)
{
m_unparsedProductInfo.Add(node.InnerText);
}
return m_unparsedProductInfo;
}
虽然我使用的路径似乎是“正确的”,但当我查看列表“m_unparsedProductInfoNodes”时,我总是得到 NULL
知道这是怎么回事吗? 我还要补充一点,如果我在 baseNode 上执行“SelectNodes”,它只会返回一个 div,唯一重要的子节点是“cs=####”,这似乎随浏览器用户代理的不同而变化。 如果我尝试以任何方式使用它(将 /cs=0 放入无法识别的浏览器的路径中),它会坚持认为我的表达式不会评估为节点集,但保留它们仍然会留下所有数据过去的问题div[2] 返回为 NULL。
尝试使用这个 XPath 表达式:
/html[1]/body[1]/div[2]/cs=0[1]/rf=141[1]/table[1]/tr[1]/td[1]/table[1]/tr[1]/td[1]
在 Firefox 中使用 Google Chrome 开发者工具和 Firebug,网页似乎在第一个表格之前有一个“cs”和“rf”标签。比如:
<cs="0">
<rf="141">
<table>
...
</table>
</rf>
</cs>
当您想要解析 known HTML 文件但未获得预期结果时,了解正在发生的情况可能会很有用。在这种情况下,我只是这样做:
string xpath = "";
//In this case I'll get all cells and see what cell has the text "296-12602-1-ND"
foreach (HtmlNode node in doc.DocumentNode.SelectNodes("//td"))
{
if (node.InnerText.Trim() == "296-12602-1-ND")
xpath = node.XPath; //Here it is
}
或者您可以在文档加载后调试应用程序,然后遍历每个子节点,直到找到要从中获取信息的节点。如果你只是在找到 InnerText 时设置断点,你可以只遍历父节点,然后继续寻找其他节点。我通常会在“监视”窗口中手动输入命令,并使用树视图进行导航以查看属性、属性和子项。
仅更新:
我从 C# 切换到更友好的 Python(我的编程经验是 asm、c 和 python,整个 OO 事物是全新的)并设法纠正我的 xpath 问题。 标签确实是问题所在,但幸运的是它是独一无二的,所以一点正则表达式和删除的行,我就处于良好状态。 我不确定为什么这样的标签会破坏 XPATH。 如果有人有一些见解,我想听听。