对于初学者来说,你不能使用HtmlDocument
(不直接)URL加载的页面。无论如何,运行这会给你一个错误。您必须单独下载内容并加载它,或者只需使用HtmlWeb
加载它。
修复方法form
处理元素的处理方法必须先设置之前您解析文档。否则,更改将不起作用。
您的示例代码假定有form
元素名为form
,并且输入可能是其直接子元素。封闭表单中的输入不一定必须是表单的子节点,它可能是树中任何位置的后代。
如果您只是在寻找所有表单字段,不管表单是什么,只要查找适当类型的所有后代即可。
string GetControlType(HtmlNode n)
{
switch (n.Name)
{
case "button": return n.GetAttributeValue("type", "(submit)");
case "input": return n.GetAttributeValue("type", "(text)");
default: return null;
}
}
string GetControlValue(HtmlNode n)
{
switch (n.Name)
{
case "button":
case "input":
return n.GetAttributeValue("value", null);
case "select":
if (n.Descendants("option").SkipWhile(x => x.Attributes["selected"] == null).FirstOrDefault() is HtmlNode o) return o.GetAttributeValue("value", null);
return n.Descendants("option").FirstOrDefault()?.GetAttributeValue("value", null);
case "textarea":
return n.InnerText;
default: return null;
}
}
HtmlNode.ElementsFlags.Remove("form");
var doc = new HtmlWeb().Load("http://www.google.com");
var fields = new[] { "button", "input", "select", "textarea" };
var query =
from n in doc.DocumentNode.Descendants()
where fields.Contains(n.Name)
let controlType = GetControlType(n)
let controlValue = GetControlValue(n)
select new
{
ControlName = n.Name,
ControlType = controlType,
Name = n.GetAttributeValue("name", null),
Value = controlValue,
OuterHtml = n.OuterHtml,
};