.net 信息采集ajax数据

关于.net信息采集的资料很多,但是如果采集的网站是ajax异步加载数据的模式,又如何采集呢?今天就把自己做信息采集时,所遇到的一些问题和心得跟大家分享一下。

采集网站的几种方式与利弊:

  1. HttpWebRequest

利用系统自带HttpWebRequest对象,采集网站内容,优点是采集效率快,但是如果网站是ajax异步加载数据的方式,是采集不到网页内容的,并且网站没有采用ajax的方式,在网页中用到了javascript,比如说:网页内容用document.write的方式输出到网页中的,这种情况也是获取不到内容的。其次还需要知道对方网站的编码格式(就是网页头部中<meta charset="utf-8"/>),如果采集时网站编码格式错误的话,会导致采集的内容是乱码。但这个是小问题,我自己当时查阅资料时找到了别人封装好的方法,但是很惭愧因为不知道作者是谁了,我会把相应的代码下载链接提供给大家。以上的问题是因为js和ajax是需要浏览器去解析的,所以导致了获取不到网页内容。

Help.HttpHelp.HttpRequest("采集的网址");

源码下载地址

2.浏览器控件

因为当时我开发的时候,用的是cs模式,相信大家同样也会用cs的模式去开发这个功能。既然是cs模式(不考虑美观)的情况下肯定是WinForm,WinForm中有自带的浏览器控件,这个是不好用的,我当时用的是Geckofx,基于火狐内核的一款浏览器控件,但是这方面的资料很少,当时遇到了一些问题都找不到解决方法,但后来还是都解决了。用了该控件就可以获取到ajax异步加载的数据,在网页加载完成之后,延迟几秒钟获取网页内容,就可以很方便的获取到网页内容,缺点是相对第一种方案来说的话会慢一些,因为它是一个浏览器控件,需要渲染html和解析js等操作。

Geckofx下载

GeckoWebBrowser webBrowser = null;

        private void Form1_Load(object sender, EventArgs e)
{
string xulrunnerPath = AppDomain.CurrentDomain.BaseDirectory + "\\bin";
Xpcom.Initialize(xulrunnerPath);
//设置为3阻止所有的弹出窗口,
GeckoPreferences.User["privacy.popups.disable_from_plugins"] = ;
//禁止加载图片
GeckoPreferences.User["permissions.default.image"] = ; webBrowser = new GeckoWebBrowser();
webBrowser.Navigate("http://www.baidu.com");
webBrowser.DocumentCompleted += DocumentCompleted;
} private void DocumentCompleted(object sender, Gecko.Events.GeckoDocumentCompletedEventArgs e)
{
var time = new System.Windows.Forms.Timer();
time.Interval = ;
time.Tick += (a, b) =>
{
time.Stop();
string html = "";
//页加载完成
GeckoHtmlElement element = null;
var geckoDomElement = webBrowser.Document.DocumentElement;
if (geckoDomElement != null && geckoDomElement is GeckoHtmlElement)
{
element = (GeckoHtmlElement)geckoDomElement;
//网页内容
html = element.InnerHtml;
txtHtml.Text = html;
  /*
                    //通过xpath 查找class为btnLogin的元素
                    GeckoNode btnLogin = webBrowser.Document.SelectFirst(".//*[@class='btnLogin']");
                    if (btnLogin != null)
                    {
                        GeckoHtmlElement ie = btnLogin as GeckoHtmlElement;
                        //手动触发点击事件
                        ie.Click();
                    }*/
}
};
time.Start();
}

3.phantomjs

phantomjs可以把它理解为也是一个浏览器控件,只不过它使用QtWebKit作为它核心浏览器的功能,使用webkit来编译解释执行JavaScript代码。利用该组件就可以很方便的获取到网页内容,同时也包括了ajax加载的数据,如果是分页的情况下,首次加载不需要延迟,如果获取第2页及以上内容的话同样也需要延迟才能获取到,并且它可以很方便的完成网页快照(就是网页截屏),至于其他的功能大家可以自己查阅一下资料。

phantomjs下载地址

  IWebDriver driver = null;

        private void btnGo_Click(object sender, EventArgs e)
{
string phantomjsDire = AppDomain.CurrentDomain.BaseDirectory; PhantomJSDriverService service = PhantomJSDriverService.CreateDefaultService(phantomjsDire);
service.IgnoreSslErrors = true;
service.LoadImages = false;
service.ProxyType = "none"; driver = new PhantomJSDriver(phantomjsDire);
/*IWindow iWindow = driver.Manage().Window;
iWindow.Size = new Size(10,10);
iWindow.Position = new Point(0, 600);*/ driver.Navigate().GoToUrl(textBox1.Text);
string html = driver.PageSource;
txtHtml.Text = html; //driver.Close();
//driver.Quit();
} private void btnPage_Click(object sender, EventArgs e)
{
// .//*[@class='next'][text()='下一页']
// .//*[@class='text']
// .//*[@class='button']
//IWebElement element = driver.FindElement(By.XPath(".//*[@class='text']"));
//给网页中文本框赋值
//element.SendKeys("4"); IWebElement btnElement = driver.FindElement(By.XPath(".//*[@class='next'][text()='下一页']"));
btnElement.Click(); var time = new System.Windows.Forms.Timer();
time.Interval = * ;
time.Tick += (a, b) =>
{
time.Stop();
string html = driver.PageSource;
txtHtml.Text = html;
};
time.Start();
}

网站内容中url地址如果是相对地址的话,就是../../a.html,这种情况要想获取绝对地址的话,可以用以下方法:

        /// <summary>
/// 获取绝对url地址
/// </summary>
/// <param name="baseUri">当前页地址</param>
/// <param name="relativeUri">相对路径地址</param>
/// <returns></returns>
public static string GetRealUrl(string baseUri, string relativeUri)
{
try
{
baseUri = System.Web.HttpUtility.UrlDecode(baseUri);
relativeUri = System.Web.HttpUtility.UrlDecode(relativeUri);
Uri baseUriModel = new Uri(baseUri);
Uri uri = new Uri(baseUriModel, relativeUri);
string result = uri.ToString();
baseUriModel = null;
uri = null;
return result;
}
catch (Exception ex)
{
}
return relativeUri;
}

总结:

以上说的第2、3种方式都可以获取到ajax异步加载的内容,同时还能通过xpath模式查找网页中的元素,例如分页标签和按钮,找到元素之后可以调用click点击事件,就能轻松的解决分页问题。好多网站分页分到最后一页的时候,处理的情况都不一样,需要自己去处理,例如有的隐藏下一页按钮、有的是禁用等等。

获取到网页内容之后,要想获取自己需要的内容,可以通过HtmlAgilityPack插件,它是通过xpath的模式查找内容。

以下我会将自己开发的信息采集系统截图发出来。

欢迎任何形式的转载,但请务必注明出处。

文案功底有限,码字不易,不喜勿喷,如果文章和代码有表述不当之处,还请不吝赐教。

.net 信息采集ajax数据的更多相关文章

  1. flask+sqlite3+echarts2+ajax数据可视化报错:UnicodeDecodeError: 'utf8' codec can't decode byte解决方法

    flask+sqlite3+echarts2+ajax数据可视化报错: UnicodeDecodeError: 'utf8' codec can't decode byte 解决方法: 将 py文件和 ...

  2. Ajax --- 数据请求

    下面主要介绍(JS原生)数据请求的主要步骤: Ajax 数据请求步骤: 1.创建XMLHttpRequest对象 2.准备数据发送 3.执行发送 4.指定回掉函数 第一步:创建XMLHttpReque ...

  3. 弹出层和ajax数据交互

    <%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs& ...

  4. VueJS搭建简单后台管理系统框架 (二) 模拟Ajax数据请求

    开发过程中,免不了需要前台与后台的交互,大部分的交互都是通过Ajax请求来完成,在服务端未完成开发时,前端需要有一个可以模拟Ajax请求的服务器. 在NodeJs环境下,通过配置express可访问的 ...

  5. ajax数据请求5(php格式)

    ajax数据请求5(php格式): <!DOCTYPE html> <html> <head> <meta charset="UTF-8" ...

  6. ajax数据请求4(xml格式)

    ajax数据请求4(xml格式): <!doctype html> <html> <head> <meta charset="utf-8" ...

  7. ajax数据请求3(数组json格式)

    ajax数据请求3(数组json格式) <!doctype html> <html> <head> <meta charset="utf-8&quo ...

  8. ajax数据请求2(json格式)

    ajax数据请求2(json格式) <!DOCTYPE html> <html> <head> <meta charset="UTF-8" ...

  9. AJAX数据请求

    ajax数据请求需要四个步骤:(请求文本内容) 1.创建XMLHttpRequest对象: 2.打开与服务起的链接: 3.发送给服务器: 4.响应就绪. <!DOCTYPE html> & ...

随机推荐

  1. [八]JavaIO之FileInputStream 与 FileOutputStream

    接下来介绍 FileInputStream  和 FileOutputStream 现在看名字应该可以看得出来: 他就是从一个文件中读取数据 或者将数据写入到一个文件中 FileInputStream ...

  2. 【Node.js】通过mongoose得到模型,不能新添字段的问题

    问题描述 通过node.js为查询到的json对象添加新的字段,对象成功保存到数据库中,但新增字段却没保存. 前几天用vue+node.js+mongodb技术做一个购物车功能的网页,发现node.j ...

  3. 用TensorFlow教你手写字识别

    博主原文链接:用TensorFlow教你做手写字识别(准确率94.09%) 如需转载,请备注出处及链接,谢谢. 2012 年,Alex Krizhevsky, Geoff Hinton, and Il ...

  4. 杭电ACM2008--数值统计

    数值统计 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submis ...

  5. Oracle day03 连表查询

    为什么要表连接进行查询? 查询部门名称为SALES的员工信息 如何进行表的连接查询? 两种方式:Sql 1992 和sql1999 sql1992sql分类    1.笛卡尔积 (表乘表)    2. ...

  6. react 阻止事件冒泡

    前言 在学习react阻止事件冒泡,需要先了解 合成事件 和 原生事件 合成事件:在jsx中直接绑定的事件,就是合成事件: 原生事件: 通过js原生代码绑定的事件,就是原生事件: react事件:re ...

  7. CSS3 box-shadow 属性 紧跟在 -webkit-, -ms- 或 -moz-

    浏览器支持 表格中的数字表示支持该属性的第一个浏览器版本号. 紧跟在 -webkit-, -ms- 或 -moz- 前的数字为支持该前缀属性的第一个浏览器版本号. 语法 box-shadow: h-s ...

  8. 钉钉JSAPI前端鉴权

    钉钉二次开发分为如下表所示三种类型的开发,只有企业内部应用才需要对JSAPI鉴权. 类型 开发方式 JSAPI鉴权 应用场景 第三方企业应用 E应用开发 不需要 用于发布到钉钉应用市场,供广大用户下载 ...

  9. Linux tail 命令

    tail 命令可用于查看文件的内容,有一个常用的参数 -f 常用于查阅正在改变的日志文件. tail -f filename 会把 filename 文件里的最尾部的内容显示在屏幕上,并且不断刷新,只 ...

  10. DevOps 工程师实际上是做什么的

    DevOps 工程师实际上是做什么的? 我们之前已经讨论过许多关于DevOps和DevOps世界的最新趋势了.但是DevOps工程师到底是做什么的? DevOps工程师以最纯粹的方式弥合了软件开发和运 ...