民间,使用C#测试网站
我需要完成一些复杂的网页抓取。
简单的目标是:登录到页面,在某些文本字段中输入一些值,单击提交,然后从检索到的页面中提取一些值。
什么是最好的方法?
- 部分单元测试第三方库?
- 在C#中手动抓取?
- 也许有专门的准备好lib吧?
- 还有其他的方法吗?
这需要在一个web应用程序内完成。
非常感谢您的帮助。
民间,使用C#测试网站
我需要完成一些复杂的网页抓取。
简单的目标是:登录到页面,在某些文本字段中输入一些值,单击提交,然后从检索到的页面中提取一些值。
什么是最好的方法?
这需要在一个web应用程序内完成。
非常感谢您的帮助。
不知道它将如何在Web应用程序内工作,但你有没有考虑给HtmlUnit一个尝试?我认为它应该很好,因为它基本上是一个无头网页浏览器。
WatiN。
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.
编辑 -
读取编辑从一个Web浏览器中执行此操作后,您可能会考虑使用WebRequest和HTML Agility Pack来验证您返回的内容:
的WebRequest:
http://msdn.microsoft.com/en-us/library/debx8sh9.aspx
HTML敏捷性包:
如果你知道什么表单提交值都应该是进入和出来,你可以创建一个应用程序C#使用HttpWebRequest并发布到页面并解析结果。这段代码是高度专业化的,供我自己使用,但你应该能够调整它,并使它做你想做的事情。它实际上是一个更大的类的一部分,可以让你添加post/get项目,然后为你提交一个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
谢谢贾斯汀。 我试过这样做,出于某种原因,我无法通过第一步。 我总是回到第一个URL,并且帖子不起作用,尽管当我手动执行时,一切似乎都正常。 你有这样的代码示例吗? – charlie 2010-08-05 19:24:13
@charlie,添加了代码。这又是一个非常具体的我们如何做事。但它会告诉你如何设置请求,如果你需要改变任何值,你当然可以这样做。很多时候,允许重定向属性需要在帖子上设置为false,以防止自动重定向转化为获取,你失去了帖子。我经常发现自己做了一个帖子,发送到另一个页面,所以你必须做一个帖子,获取重定向网址并重新发布到该页面。 HTTP提交可能有点棘手,可以采取一些工作来确保正确。 – Justin 2010-08-05 19:38:37
我要说硒,但如果你打算这样做,内部我可能会做一些这样的NUnit写的测试,然后从web应用程序运行它们。
在web-app但内心为什么?这就像在车内对汽车进行碰撞测试。
+1我喜欢这个比喻。 – 2010-08-05 19:28:28
好问题。答案是这样的: 我正在为巴士公司工作。我们与许多巴士供应商合作。当我们接到服务电话时,代理商需要向许多提供商查询最便宜的价格。 因此,对于所有提供API的供应商而言,解决方案非常简单。 但是,对于那些提供要求我们登录才能获得价格的网站,我们需要编写这样的应用程序。 现在:因为我们的内部系统是作为一个网络应用程序编写的,所以这个爬行应该是这个网络应用程序的一部分... 奇怪的是一见钟情,但在重新思考时非常有用... – charlie 2010-08-05 19:29:24
我们是不是真的在测试网络应用程序?也许改变你的问题,以反映你正在考虑从外部网站抓取数据以便在你的web应用程序中使用将是适当的? – Doon 2010-08-05 19:41:51
如果您正在寻找更轻量级的产品,请尝试使用SimpleBrowser for .Net--在Github上开源。
看起来很有希望特别使用jQuery像选择器 – geekonweb 2012-04-03 05:52:24
惊讶HTMLAgilityPack没有提到。这是迄今为止最简单的使用。
似乎让我更接近我们的目标... 我会仔细研究它几分钟,并在这里发布结果。 谢谢!以后再聊。 – charlie 2010-08-05 19:44:16
这是我卡住的地方:它需要包含Java中的IKVM.OpenJDK.Security.dll才能在> net中使用,但我不知道如何去做...... – charlie 2010-08-05 22:04:39
不,你不需要需要Java SDK中的任何东西。如果你看看你的IKVM下载目录,你会发现一堆DLLS,其中一个是IKVM.OpenJDK.Security.dll。您需要像在.NET程序集中那样,在项目中添加对该项目的引用。您还需要添加对IKVM.OpenJDK.Core,IKVM.OpenJDK.Text,IKVM.OpenJDK.Util,IKVM.OpenJDK.XML.API,IKVM.OpenJDK.XML.Parse,IKVM.OpenJDK.XML的引用。路径和IKVM.Runtime.dll。 – Mhmmd 2010-08-05 22:47:20