2009-12-23 101 views
0

我们的情况: 我们的团队需要从第三方网站检索日志信息(具体而言,此日志 信息是通话记录 - 我们的客户租用866号码,当来电时,他们协助 人,并且需要在我们的应用程序中做相应的记录,这将与当前通话的 相对应)。我们的客户在第三方有一个网络帐户,允许他们查看当前的通话记录(日期/时间,电话号码,每次通话时间等) 。使用ASP.NET从第三方登录网站检索HTML页面

我联系了他们网站的开发人员,并询问了API或其他方法将我们的数据库与他们不断更新的数据库进行同步 。他们目前不支持API。我 通知他们我的情况,他们完全没问题,我们可以通过任何方式检索 信息(bot/crawler)。 *第三方表示,他们正在研究的API,但不能给我们 一般的时间表何时将达到...并且与每一位客户,他们需要尽快开始 生产。

我完全理解,如果第三方改变他们的HTML布局,它可能会导致我们轻微的头痛(从网页排序数据)。这就是说,这是一个解决长期问题的临时解决方案 。一旦他们实现了他们的API,我们会将它们切换到它。

所以我的问题是这样的: 什么是登录到第三方网站的最佳方式(见图片:http://i903.photobucket.com/albums/ac239/jreedinc/customtf.jpg) 和检索某些HTML页面?我们已经审查了webcrawlers的源代码,但它们都不具备存储cookies并将信息发回网站的功能(以登录信息的形式)。我们希望在ASP.NET中执行此操作。

有另一种方式来完成登录到网站,然后检索上述信息?

回答

0

我用了一个最近呼吁WebQL(其网络刮刀工具的工具,让开发人员使用SQL的语法来从网页刮信息。

WebQL on Wikipedia

0

这实际上是一个相对简单的操作。什么你需要做的就是在页面的截图帖回(像login.php中,等等),然后建立一个WebRequest的,以页面,你必须登录数据。你很可能会得到一个的CookieContainer即会请将您的登录Cookie用于所有后续请求。

你可以看一下这个MSDN article对于如何做到这一点的基础知识,但他们写了是一种混乱。查看最后的社区评论,了解如何发布页面变量(例如用户名和密码)的示例。您需要确保您在随后的请求中传递cookiecontainer。

不幸的是,.NET本身并没有像WWW :: Mechanize这样的东西,但Webclient确实有一个“上传值”,这可能会使它更容易。您仍然必须手动解析页面以确定需要传递的字段。

2

你需要使用类是System.Net命名空间。下面是概念代码的一些快速和肮脏的证明。登录到使用表单登录+ Cookie进行安全性的网站,然后刮取页面的HTML输出。

为了解析HTML结果,您需要使用额外的工具。

可能的HTML解析工具。

SgmlReader,可以将HTML转换为XML。然后,您使用.NET的XML功能从XML中提取数据。
http://code.msdn.microsoft.com/SgmlReader

HTML Agility Pack允许对HTML文档进行XPath查询。
http://htmlagilitypack.codeplex.com/

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 


class WebWorker { 

/// <summary> 
/// Cookies for use by web worker 
/// </summary> 
private System.Collections.Generic.List `<System.Net.Cookie` > cookies = new List <System.Net.Cookie>(); 


public string GetWebPageContent(string url) { 
    System.Net.HttpWebRequest request = (System.Net.HttpWebRequest) System.Net.WebRequest.Create(url); 
    System.Net.CookieContainer cookieContainer = new System.Net.CookieContainer(); 
    request.CookieContainer = cookieContainer; 
    request.Method = "GET"; 

    //add cookies to maintain session state 
    foreach(System.Net.Cookie c in this.cookies) { 
    cookieContainer.Add(c); 
    } 



    System.Net.HttpWebResponse response = request.GetResponse() as System.Net.HttpWebResponse; 


    System.IO.Stream responseStream = response.GetResponseStream(); 

    System.IO.StreamReader sReader = new System.IO.StreamReader(responseStream); 

    System.Diagnostics.Debug.WriteLine("Content:\n" + sReader.ReadToEnd()); 


    return sReader.ReadToEnd(); 

} 

public string Login(string url, string userIdFormFieldName, string userIdValue, string passwordFormFieldName, string passwordValue) { 

    System.Net.HttpWebRequest request = (System.Net.HttpWebRequest) System.Net.WebRequest.Create(url); 
    System.Net.CookieContainer cookieContainer = new System.Net.CookieContainer(); 
    request.CookieContainer = cookieContainer; 
    request.Method = "POST"; 
    request.ContentType = "application/x-www-form-urlencoded"; 
    string postData = System.Web.HttpUtility.UrlEncode(userIdFormFieldName) + "=" + System.Web.HttpUtility.UrlEncode(userIdValue) + 
    "&" + System.Web.HttpUtility.UrlEncode(passwordFormFieldName) + "=" + System.Web.HttpUtility.UrlEncode(passwordValue); 

    request.ContentLength = postData.Length; 

    request.AllowAutoRedirect = false; //allowing redirect seems to loose cookies 
    byte[] postDataBytes = System.Text.Encoding.UTF8.GetBytes(postData); 
    System.IO.Stream requestStream = request.GetRequestStream(); 
    requestStream.Write(postDataBytes, 0, postDataBytes.Length); 
    System.Net.HttpWebResponse response = request.GetResponse() as System.Net.HttpWebResponse; 

    // System.Diagnostics.Debug.Write(WriteLine(new StreamReader(response.GetResponseStream()).ReadToEnd()); 

    System.IO.Stream responseStream = response.GetResponseStream(); 

    System.IO.StreamReader sReader = new System.IO.StreamReader(responseStream); 

    System.Diagnostics.Debug.WriteLine("Content:\n" + sReader.ReadToEnd()); 
    this.cookies.Clear(); 

    if (response.Cookies.Count > 0) { 
    for (int i = 0; i < response.Cookies.Count; i++) { 
    this.cookies.Add(response.Cookies[i]); 
    } 
    } 

    return "OK"; 
} 


} //end class 

//样品使用类

WebWorker worker = new WebWorker(); 
worker.Login("http://localhost/test/default.aspx", "uid", "bob", "pwd", "secret"); 
worker.GetWebPageContent("http://localhost/test/default.aspx");