我正在尝试使用HtmlAgilityPack获取所有控件名称和控件类型(如果它是文本框或复选框等)。我总是将值视为null。可能是什么问题?
HtmlDocument htmlCode = new HtmlDocument();
htmlCode.LoadHtml("http://www.google.com");
//var htmlCode = client.DownloadString("http://www.google.com");
HtmlNode.ElementsFlags.Remove("form");
HtmlNode myForm = htmlCode.GetElementbyId("form");
foreach (HtmlNode node in myForm.Elements("input"))
{
HtmlAttribute valueAttribute = node.Attributes["value"];
if (valueAttribute != null)
{
Console.WriteLine(valueAttribute.Value);
}
}
答案 0 :(得分:1)
对于初学者,您无法使用HtmlDocument
(而非直接)从网址加载网页。无论如何,运行会给你一个错误。您必须单独下载内容并加载它,或者只需使用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,
};