phantomjs获取动态页面ajax,C#利用phantomJS抓取AjAX动态页面(示例代码)

在C#中,一般常用的请求方式,就是利用HttpWebRequest创建请求,返回报文。但是有时候遇到到动态加载的页面,却只能抓取部分内容,无法抓取到动态加载的内容。

如果遇到这种的话,推荐使用phantomJS无头浏览器。

开发之前,先准备两样东西。

1. phantomJS-2.1.1   官方下载地址:http://phantomjs.org/download.html

22185817055843f896c278e3aba8f37e.jpg

2. JS脚本文件,本人命名为codes.js.内容如下。起初我并没有配置page的settings信息,导致在抓取有些异步页面卡死。主要原因是由于没有配置请求头部信息。

var page = require(‘webpage‘).create(), system = require(‘system‘);

var url = system.args[1];

var interval = system.args[2];

var settings = {

timeout: interval,

encoding: "gb2312",

operation: "GET",

headers: {

"User-Agent": system.args[3],

"Accept": system.args[4],

"Accept-Language": "zh-CN,en;q=0.7,en-US;q=0.3",

"Connection": "keep-alive",

"Upgrade-Insecure-Requests": 1,

"Connection": "keep-alive",

"Pragma": "no-cache",

"Cache-Control": "no-cache",

"Referer": system.args[5]

}

}

page.settings = settings;

page.open(url, function (status) {

phantom.outputEncoding = "gb2312";

if (status !== ‘success‘) {

console.log(‘Unable to post!‘);

phantom.exit();

} else {

setTimeout(function () {

console.log(page.content);

phantom.exit();

}, interval);

}

});

准本完成之后,需要将这两份文件放到你的项目中。如下:

27bd7815f93b41949790fa7f526d29e4.jpg

这些都没问题了,就可以开始写后台代码了。

///

/// 利用phantomjs 爬取AJAX加载完成之后的页面

/// JS脚本刷新时间间隔为1秒,防止页面AJAX请求时间过长导致数据无法获取

///

///

///

public static string GetAjaxHtml(string url, HttpConfig config, int interval = 1000)

{

try

{

string path = System.AppDomain.CurrentDomain.BaseDirectory.ToString();

ProcessStartInfo start = new ProcessStartInfo(path + @"phantomjsphantomjs.exe");//设置运行的命令行文件问ping.exe文件,这个文件系统会自己找到

start.WorkingDirectory = path + @"phantomjs";

设置命令参数

string commond = string.Format("{0} {1} {2} {3} {4} {5}", path + @"phantomjscodes.js", url, interval, config.UserAgent, config.Accept, config.Referer);

start.Arguments = commond;

StringBuilder sb = new StringBuilder();

start.CreateNoWindow = true;//不显示dos命令行窗口

start.RedirectStandardOutput = true;//

start.RedirectStandardInput = true;//

start.UseShellExecute = false;//是否指定操作系统外壳进程启动程序

Process p = Process.Start(start);

StreamReader reader = p.StandardOutput;//截取输出流

string line = reader.ReadToEnd();//每次读取一行

string strRet = line;// sb.ToString();

p.WaitForExit();//等待程序执行完退出进程

p.Close();//关闭进程

reader.Close();//关闭流

return strRet;

}

catch (Exception ex)

{

return ex.Message.ToString();

}

}

public class HttpConfig

{

///

/// 网站cookie信息

///

public string Cookie { get; set; }

///

/// 页面Referer信息

///

public string Referer { get; set; }

///

/// 默认(text/html)

///

public string ContentType { get; set; }

public string Accept { get; set; }

public string AcceptEncoding { get; set; }

///

/// 超时时间(毫秒)默认100000

///

public int Timeout { get; set; }

public string UserAgent { get; set; }

///

/// POST请求时,数据是否进行gzip压缩

///

public bool GZipCompress { get; set; }

public bool KeepAlive { get; set; }

public string CharacterSet { get; set; }

public HttpConfig()

{

this.Timeout = 100000;

this.ContentType = "text/html; charset=" + Encoding.UTF8.WebName;

this.UserAgent = "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Safari/537.36";

this.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8";

this.AcceptEncoding = "gzip,deflate";

this.GZipCompress = false;

this.KeepAlive = true;

this.CharacterSet = "UTF-8";

}

}

这些也是本人今天才接触到的,整理下自己的想法。有错误之处还希望能够指出。