HtmlAgilityPack获取页面控件名称和属性类型

时间:2016-12-27 01:58:52

标签: c# html-agility-pack

我正在尝试使用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);
                }
            }

1 个答案:

答案 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,
    };