我正在尝试使用HTML agility pack动态列出HTML表单中的所有节点,这意味着我不知道属性的名称和输入名称。 问题是当我想获得与输入相对应的标签时。
<form name="input" action="html_form_action.asp" method="get">
Username: <input type="text" name="user" />
<input type="submit" value="Submit" />
</form>
所以在这里我想写用户名然后输入,在这个例子中看起来很明显,但有时它们不是直接的兄弟姐妹,会有很多隐藏的输入或其他标签。
另一个例子:
<input type=hidden name="startDate">
<TR> <TD bgColor=#008088 colSpan=2 class="headfont">
<FONT color=#FFFFFF> <B>* Enter ur username and password</B> </FONT>
</TD></TR>
<TR>
<TD bgColor=#9ccdcd class="datafont"><FONT color=black>Username</FONT></TD>
<TD bgColor=#9ccdcd class="datafont">
<INPUT tabIndex=1 name=stuNum
autocomplete="off" size="20"></TD></TR>
<TR>
在我的项目中使用C#winforms。
我没有什么想法,但是他们会花很多时间,所以我认为既然我是HTML敏捷包的新手就会有一种方法或一些捷径可以获得它,任何建议?
答案 0 :(得分:2)
这样的事情应该有效。
static IEnumerable<Tuple<string, HtmlNode>> GetInputNodes(HtmlDocument doc, params string[] fields)
{
var form = doc.DocumentNode.SelectSingleNode("//form");
foreach (var field in fields)
{
var fieldNode = form.ChildNodes
.OfType<HtmlTextNode>()
.Where(node => node.Text.Trim().StartsWith(field, StringComparison.OrdinalIgnoreCase))
.SingleOrDefault();
if (fieldNode == null)
continue;
var input = FindCorrespondingInputNode(fieldNode);
if (input != null)
yield return Tuple.Create(field, input);
}
}
static HtmlNode FindCorrespondingInputNode(HtmlTextNode fieldNode)
{
for (var currentNode = fieldNode.NextSibling;
currentNode != null && currentNode.NodeType != HtmlNodeType.Text;
currentNode = currentNode.NextSibling)
{
if (currentNode.Name == "input"
&& !currentNode.Attributes["type"].Value.Contains("hidden"))
{
return currentNode;
}
}
return null;
}
然后使用它,只需传入要获取输入元素的字段的名称。
GetInputNodes(doc, "username");
只是一个警告,似乎HtmlAgilityPack并没有像它应该的那样关闭表单。因此,您必须指定在加载html之前应关闭表单元素。没有它,HAP将无法识别该表单有任何子节点。
var doc = new HtmlDocument();
HtmlNode.ElementsFlags["form"] = HtmlElementFlag.Closed;
doc.Load(url);