C#和java調用phantomjs採集ajax加載生成的網頁

     日前有采集需求,當我把所有的對應頁面的鏈接都拿到手,準備開始根據鏈接去採集(寫爬蟲爬取)對應的終端頁的時候,發覺用程序獲取到的數據根本沒有對應 的內容,可是我的瀏覽器看到的內容明明是有的,於是瀏覽器查看源代碼也發覺沒有,此時想起該網頁應該是ajax加載的。不知道ajax的小朋友可以去學下 web開發啦。
    採集ajax生成的內容手段不外乎兩種。一種是通過http觀察加載頁面時候的請求,然後我們模仿該請求去得到對應的內容,第二種則是模仿瀏覽器行爲去渲 染這個頁面得到內容。我在這裏決定採用第二種方式,之前一直玩webkit,不過一直要加載頁面太浪費資源了,此時瞭解到有一個好玩的玩意 phantomjs,這是個可以用命令行來操作webkit的玩意,然後也可以直接在裏面用js的api去操作頁面(當然,我這邊比較簡單就懶得用了)。
    下載完phantomjs之後直接解壓就可以使用,然後在path目錄加入phantomjs的路徑(以便直接在命令行就可以執行phantomjs命令)。
    接下來要完成個代碼,一個是用phantomjs去獲取頁面(採用js編寫行爲),一個是採用java去調用phantomjs來達到獲取內容的作用,接下來直接貼代碼。
codes.js
/codes.js   
system = require('system')   
address = system.args[1];//獲得命令行第二個參數 接下來會用到   
//console.log('Loading a web page');   
var page = require('webpage').create();   
var url = address;   
//console.log(url);   
page.open(url, function (status) {   
    //Page is loaded!   
    if (status !== 'success') {   
        console.log('Unable to post!');   
    } else {   
        //console.log(page.content);   
        //var title = page.evaluate(function() {   
        //  return document.title;//示範下如何使用頁面的jsapi去操作頁面的  www.oicqzone.com 
        //  });   
        //console.log(title);   
        //console.log(encodeURIComponent(page.content));    
        console.log(page.content);   
    }      
    phantom.exit();   
});    
 
上述的js代碼估計應該沒幾個看不懂的。。。
接下來貼java代碼!
import org.apache.commons.io.IOUtils;   
   
import java.io.*;   
   
/**  
 * Created with IntelliJ IDEA.  
 * User: lsz  
 * Date: 14-4-22  
 * Time: 下午1:17  
 * utils for http  
 */   
public class HttpUtils {   
    public static String getAjaxCotnent(String url) throws IOException {   
        Runtime rt = Runtime.getRuntime();   
        Process p = rt.exec("phantomjs.exe c:/phantomjs/codes.js "+url);//這裏我的codes.js是保存在c盤下面的phantomjs目錄   
        InputStream is = p.getInputStream();   
        BufferedReader br = new BufferedReader(new InputStreamReader(is));   
        StringBuffer sbf = new StringBuffer();   
        String tmp = "";   
        while((tmp = br.readLine())!=null){   
            sbf.append(tmp);   
        }   
        //System.out.println(sbf.toString());   
        return sbf.toString();   
    }   
   
    public static void main(String[] args) throws IOException {   
        getAjaxCotnent("http://www.plusweb.cn");   
    }   
}   
 C#實現代碼
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.IO;
using System.Net;
using System.Threading;

namespace phantomjs
{
    class Program
    {
        static void Main(string[] args)
        {

            // String str = getAjaxCotnent("http://www.plusweb.cn");//測試使用
            new Program().listHttp();
           
        }

        public static String getAjaxCotnent(String url)
        {

            ProcessStartInfo start = new ProcessStartInfo(Environment.CurrentDirectory + "//phantomjs//phantomjs.exe");//設置運行的命令行文件問ping.exe文件,這個文件系統會自己找到
            //如果是其它exe文件,則有可能需要指定詳細路徑,如運行winRar.exe
            start.Arguments = "phantomjs//code.js" + " " + url;//設置命令參數
            StringBuilder sb = new StringBuilder();
            start.CreateNoWindow = false;//不顯示dos命令行窗口
            start.RedirectStandardOutput = true;//
            start.RedirectStandardInput = true;//
            start.UseShellExecute = false;//是否指定操作系統外殼進程啓動程序
            Process p = Process.Start(start);
            
            string encoding = p.StandardOutput.CurrentEncoding.ToString();
            StreamReader reader = p.StandardOutput;//截取輸出流
            string line = reader.ReadLine();//每次讀取一行
            sb.AppendLine(line);
            while (!reader.EndOfStream)
            {
                
                line = reader.ReadLine();
                sb.AppendLine(line);
            }
            p.WaitForExit();//等待程序執行完退出進程
            p.Close();//關閉進程 
            reader.Close();//關閉流
            string strRet =  System.Web.HttpUtility.UrlDecode(sb.ToString());
           return strRet;
        }



        private void listHttp()
        {



            using (HttpListener listerner = new HttpListener())
            {
                string urllister = System.Configuration.ConfigurationSettings.AppSettings["listurl"];
                listerner.AuthenticationSchemes = AuthenticationSchemes.Anonymous;//指定身份驗證 Anonymous匿名訪問
                //listerner.Prefixes.Add(urllister);               
                listerner.Prefixes.Add("http://localhost/web/");
                listerner.Start();
                Console.WriteLine("WebServer Start Successed.......");
                while (true)
                {
                    //等待請求連接
                    //沒有請求則GetContext處於阻塞狀態
                    HttpListenerContext ctx = listerner.GetContext();
                    ctx.Response.StatusCode = 200;//設置返回給客服端http狀態代碼
                    string url = ctx.Request.QueryString["url"];
                    //使用Writer輸出http響應代碼
                    using (StreamWriter writer = new StreamWriter(ctx.Response.OutputStream))
                    {
                        writer.WriteLine(getAjaxCotnent(url));
                        writer.Close();
                        ctx.Response.Close();
                    }

                }
                listerner.Stop();
            }
        }
    }

}
 啓動器c#程序訪問以下地址:
http://localhost/web/?url=http%3A%2F%2Fwww.plusweb.cn
進行測試
 
其實原理很簡單,就是通過進程間通信用java調用phantomjs這個組件去請求渲染頁面,不過這種做法因爲每次都要重新啓動phantomjs進 程,所以比較慢,還有另外一種直接用phantomjs加載頁面後,把內容post給我們自定義的一個http後端接收數據,會更快一點。
phantomjs下載地址:
發佈了401 篇原創文章 · 獲贊 7 · 訪問量 13萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章