【发布时间】:2010-08-05 19:16:16
【问题描述】:
伙计们,
我需要完成一些复杂的网络爬取。
简单来说目标:登录到一个页面,在一些文本字段中输入一些值,单击提交,然后从检索到的页面中提取一些值。
最好的方法是什么?
- 一些单元测试 3rd 方库?
- 在 C# 中手动爬取?
- 也许有专门为此准备的库?
- 还有其他方法吗?
这需要在网络应用中完成。
非常感谢您的帮助。
【问题讨论】:
标签: c# web-crawler http-post
伙计们,
我需要完成一些复杂的网络爬取。
简单来说目标:登录到一个页面,在一些文本字段中输入一些值,单击提交,然后从检索到的页面中提取一些值。
最好的方法是什么?
这需要在网络应用中完成。
非常感谢您的帮助。
【问题讨论】:
标签: c# web-crawler http-post
等待。
var browser = new IE();
browser.GoTo("http://www.mywebsite.com");
browser.TextField("username").TypeText("username goes here"); // alternatively, use .Value = if you don't need to simulate keystrokes.
browser.Button(Find.ById("submitButton")).Click();
并在返回页面上的断言中:
Assert.AreEqual("You are logged in as Username.", ie.TextField("username").Value); // you can essentially check any HTML tag, I just used TextField for brevity.
编辑 -
在从网络浏览器中阅读有关执行此操作的编辑后,您可能会考虑使用 WebRequest 和 HTML Agility Pack 来验证您返回的内容:
网络请求:
http://msdn.microsoft.com/en-us/library/debx8sh9.aspx
HTML 敏捷包:
【讨论】:
不确定它将如何在 Web 应用程序中工作,但您是否考虑过尝试HtmlUnit?我认为它应该可以正常工作,因为它基本上是一个无头网络浏览器。
Steven Sanderson 有一个blog post about using HtmlUnit in .NET code。
【讨论】:
如果您正在寻找更轻量级的东西,请尝试 SimpleBrowser for .Net - 在 Github 上开源。
【讨论】:
我本来想说 Selenium,但如果你要在内部进行,我可能会使用 NUnit 之类的东西来编写测试,然后从 Web 应用程序运行它们。
为什么在网络应用程序中?这就像在车内对汽车进行碰撞测试。
【讨论】:
如果您知道表单 post 值应该输入和输出的内容,您可以在 C# 中创建一个使用 HttpWebRequest 并发布到页面并解析结果的应用程序。这段代码是高度专业化的,供我自己使用,但你应该能够对其进行调整,让它做你想做的事。它实际上是一个更大的类的一部分,它允许您向其中添加发布/获取项目,然后为您提交一个 http 请求。
// this is for the query string
char[] temp = new char[1];
temp[0] = '?';
// create the query string for post/get types
Uri uri = _type == PostType.Post ? new Uri( url ) : new Uri( ( url + "?" + postData ).TrimEnd( temp ) );
// create the request
HttpWebRequest request = (HttpWebRequest)WebRequest.Create( uri );
request.Accept = _accept;
request.ContentType = _contentType;
request.Method = _type == PostType.Post ? "POST" : "GET";
request.CookieContainer = _cookieContainer;
request.Referer = _referer;
request.AllowAutoRedirect = _allowRedirect;
request.UserAgent = "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1.3) Gecko/20090824 Firefox/3.5.3";
// set the timeout to a big value like 2 minutes
request.Timeout = 120000;
// set our credentials
request.Credentials = CredentialCache.DefaultCredentials;
// if we have a proxy set its creds as well
if( request.Proxy != null )
{
request.Proxy.Credentials = CredentialCache.DefaultCredentials;
}
// append post items if we need to
if( !String.IsNullOrEmpty( _body ) )
{
using( StreamWriter sw = new StreamWriter( request.GetRequestStream(), Encoding.ASCII ) )
{
sw.Write( _body );
}
}
if( _type == PostType.Post &&
String.IsNullOrEmpty( _body ) )
{
using( Stream writeStream = request.GetRequestStream() )
{
UTF8Encoding encoding = new UTF8Encoding();
byte[] bytes = encoding.GetBytes( postData );
writeStream.Write( bytes, 0, bytes.Length );
}
}
if( _headers.Count > 0 )
{
request.Headers.Add( _headers );
}//end if
// we want to keep this open for a bit
using( HttpWebResponse response = (HttpWebResponse)request.GetResponse() )
{
// TODO: do something with the response
}//end using
【讨论】: