如何以编程方式在第三人的网站上提交某些ID的表格

时间:2014-10-20 14:13:52

标签: c# html forms

在网站上:http://www.e-korepetycje.net/有用于登录的表单:

<form method="post" action="http://www.e-korepetycje.net/zaloguj" id="login-box">
   <fieldset>
      <ul>
         <li><input type="text" name="login" placeholder="Login or email"></li>
         <li><input type="password" name="passwd" placeholder="Password"></li>
         <li><input type="submit" value="Log in"></li>
      </ul>
   </fieldset>
</form>

我想填写输入字段loginpasswd,然后通过C#以编程方式提交此表单。

我见过THIS TOPIC,但最受欢迎的答案只是某些代码,它们没有引用问题的HTML,也没有回复引用的HTML,所以很难理解


更新

我使用了Adriano Repetti的答案。我在这里得到例外var inputField = Descendants(form).First(x => x.GetAttribute("name") == "login");序列不包含指定的元素(InvalidOperationException)。

使用System; 使用System.Collections.Generic; 使用System.ComponentModel; 使用System.Data; 使用System.Drawing; 使用System.Linq; 使用System.Text; 使用System.Threading.Tasks; 使用System.Windows.Forms;

命名空间WindowsFormsApplication1 {     public partial class Form1:Form {         public Form1(){             的InitializeComponent();             WebBrowser wb = new System.Windows.Forms.WebBrowser();             wb.DocumentCompleted + = wb_DocumentCompleted;             wb.Navigate( “http://www.e-korepetycje.net/”);             Console.WriteLine(“导航后”);         }         public static IEnumerable Descendants(HtmlElement root){             foreach(root.Children中的HtmlElement子句){                 屈服回归孩子;

            if (!child.CanHaveChildren)
                continue;

            foreach (var subChild in Descendants(child))
                yield return child;
        }
    }

    static void wb_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e) {

        WebBrowser wb = ((WebBrowser)sender);
        if (e.Url.AbsolutePath == (sender as WebBrowser).Url.AbsolutePath) {
            Console.WriteLine("COMPLETED");
            //HtmlElementCollection elems = wb.Document.GetElementsByTagName("HTML");
            //Console.WriteLine(elems[0].OuterHtml);
            var form = wb.Document.GetElementById("login-box");
            Console.WriteLine(Descendants(form).Count());


            var inputField = Descendants(form).First(x => x.GetAttribute("name") == "login");
            inputField.SetAttribute("value", "login");

            inputField = Descendants(form).First(x => x.GetAttribute("name") == "passwd");
            inputField.SetAttribute("value", "passwd");

            var submitButton = Descendants(form).First(x => x.TagName == "input" && x.GetAttribute("type") == "submit");
            submitButton.RaiseEvent("click");
        }


    }
}
}

输出

After navigate
'WindowsFormsApplication1.vshost.exe' (CLR v4.0.30319: WindowsFormsApplication1.vshost.exe): Loaded 'C:\Windows\assembly\GAC\Microsoft.mshtml\7.0.3300.0__b03f5f7f11d50a3a\Microsoft.mshtml.dll'. Module was built without symbols.
COMPLETED
'WindowsFormsApplication1.vshost.exe' (CLR v4.0.30319: WindowsFormsApplication1.vshost.exe): Loaded 'C:\Windows\Microsoft.Net\assembly\GAC_MSIL\System.Core.resources\v4.0_4.0.0.0_pl_b77a5c561934e089\System.Core.resources.dll'. Module was built without symbols.
A first chance exception of type 'System.InvalidOperationException' occurred in System.Core.dll
12
'WindowsFormsApplication1.vshost.exe' (CLR v4.0.30319: WindowsFormsApplication1.vshost.exe): Loaded 'C:\Windows\Microsoft.Net\assembly\GAC_MSIL\System.Configuration\v4.0_4.0.0.0__b03f5f7f11d50a3a\System.Configuration.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.

更新2

我也尝试过:

var inputField =  wb.Document.GetElementsByTagName("text")["login"];

但它会返回null

2 个答案:

答案 0 :(得分:2)

以编程方式与网站进行交互的最简单方法(来自C#应用程序)IMO将使用WebBrowser控件:

WebBrowser wb = new System.Windows.Forms.WebBrowser();
wb.Navigate(" http://www.e-korepetycje.net/");

现在该站点已加载到嵌入式Web浏览器(基于IE)中。你可以注入一些JavaScript代码来执行这个任务,但是从C#也很容易。完成文档下载和DOM解析后,您可以找到该表单(使用其ID)。将所有后续代码放在wb.Document.DocumentCompleted事件处理程序中(如果您愿意,也可以等待wb.Document.DocumentStatus属性)。

var form = wb.Document.GetElementById("login-box");

然后在其中找到提交按钮:

var submitButton = form
    .Descendants()
    .First(x => x.TagName == "input" && x.GetAttribute("type") == "submit");

然后模拟点击:

submitButton.RaiseEvent("click");

我使用了一个小帮助函数来遍历HtmlElement的所有子项:

public static IEnumerable<HtmlElement> Descendants(this HtmlElement root)
{
    foreach (HtmlElement child in root.Children)
    {
        yield return child;

        if (!child.CanHaveChildren)
            continue;

        foreach (var subChild in Descendants(child))
            yield return child;
    }
}

顺便说一句,如果你想要注入JavaScript代码,那么它必须是这样的(当然你需要更多的代码来用Document.CreateElement()创建脚本函数并用Document.InvokeScript()来调用它。 ):

document.forms["login-box"].submit();

请注意,同样的技巧也可用于填写表格:

var inputField = form
    .Descendants()
    .First(x => x.GetAttribute("name") == "login");

inputField.SetAttribute("value", "login name to post");

当然,所有这些代码都可以推广到足以重用......

答案 1 :(得分:0)

您可以创建一个Windows窗体,向其添加WebBrowser控件,然后将URL设置为网站。将url加载到浏览器控件后,您可以使用Document方法访问InvokeScript(script)属性以调用脚本(以填充用户标识和密码并提交表单)。