0

我们的情况:我们的团队需要从第三方网站检索日志信息(具体来说,这个日志信息是通话记录——我们的客户租用了一个866号码。当有电话进来时,他们会协助人们并需要在我们的应用程序中相应地做笔记这将与当前呼叫相对应)。我们的客户有一个第三方的网络帐户,允许他们查看当前的通话记录(日期/时间、电话号码、每次通话的时间等)。

我联系了他们网站的开发人员,询问了 API 或任何其他将我们的数据库与他们不断更新的数据库同步的方法。他们目前不支持 API。我告诉他们我的情况,他们可以通过任何方式检索信息(机器人/爬虫)。*第 3 方表示他们正在开发 API,但无法向我们提供关于何时启动的一般时间表……并且与每个客户一样,他们需要尽快开始生产。

我完全理解如果第三者改变他们的 HTML 布局,可能会让我们有点头疼(从网页中排序数据)。话虽如此,这是对长期问题的临时解决方案。一旦他们实现了他们的 API,我们将把他们切换到它。

所以我的问题是:登录 3rd 方网站(参见图片:http: //i903.photobucket.com/albums/ac239/jreedinc/customtf.jpg)并检索某些 HTML 页面的最佳方式是什么?我们已经审查了网络爬虫的源代码,但它们都没有能力存储 cookie 并将信息发布回网站(带有登录信息)。我们更愿意在 ASP.NET 中执行此操作。

是否有另一种方法可以完成登录网站,然后检索所述信息?

4

3 回答 3

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");  
于 2009-12-23T21:01:08.170 回答
0

这其实是一个比较简单的操作。您需要做的是获取屏幕截图发回的页面(例如 login.php 等),然后使用您拥有的登录数据构造对该页面的 webrequest。您很可能会取回一个 cookie 容器,该容器将拥有您的登录 cookie 以用于所有后续请求。

您可以查看这篇MSDN 文章了解如何操作的基础知识,但他们的文章有点令人困惑。查看最后的社区评论,了解如何发回页面变量(如用户名和密码)的示例。您需要确保在后续请求中传递 cookiecontainer。

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

于 2009-12-23T20:54:47.233 回答
0

我最近使用了一个名为 WebQL 的工具(它是一种网络抓取工具,可让开发人员使用类似 SQL 的语法从网页中抓取信息。

维基百科上的 WebQL

于 2009-12-23T20:42:38.363 回答