Извлечение данных из формы HTML с использованием пакета Agility HTML - PullRequest
3 голосов
/ 08 ноября 2011

Я пытаюсь перечислить все узлы в HTML-форме, которую я использую динамически, используя пакет agility 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, найдется способ или какой-нибудь ярлык, чтобы его получить ,,, Есть предложения?

1 Ответ

2 голосов
/ 08 ноября 2011

Как-то так должно работать.

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);
...