Android网页爬虫

版权声明:转载请说明出处:http://blog.csdn.net/yhaolpz https://blog.csdn.net/yhaolpz/article/details/60087849

爬取静态页面

需求:获取本人博客页面的 title “yhao的博客- 博客频道 - CSDN.NET”

首先通过okhttp以get方式请求页面:

 final String url = "http://blog.csdn.net/yhaolpz?viewmode=contents";
        Request request = new Request.Builder().url(url).build();
        mOkHttpClient.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                Log.e(TAG, "onFailure ");
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                if (response.code() == 200) {
                    String html = response.body().string();
                    Log.d(TAG, "onResponse: " + html);                 
                }
            }
        });

返回页面数据onResponse如下:

 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
 <html xmlns="http://www.w3.org/1999/xhtml">                                                                  
 <head>  
 <script type="text/javascript" src="http://c.csdnimg.cn/pubfooter/js/tracking.js" charset="utf-8"></script>  
 <script type="text/javascript">
    var protocol = window.location.protocol;
    document.write('<script type="text/javascript" src="' + protocol + '//csdnimg.cn/pubfooter/js/repoAddr2.js?v=' + Math.random() + '"></' + 'script>');
 </script>                                                                                                                          
 <meta http-equiv="Cache-Control" content="no-siteapp" />
 <link rel="alternate" media="handheld" href="#" />

 <title>yhao的博客- 博客频道 - CSDN.NET</title>

 ......

怎么获取《title》标签中的字符串值呢?

  1. 正则表达式
  2. 专业解析Html工具(如Jsoup)

其中正则表达式易出错,效率低,略过。

Jsoup使用步骤:

1.导入jar;或 Gradle: compile ‘org.jsoup:jsoup:1.10.2’

2.然后直接在程序中使用:

Document doc = Jsoup.parse(html);
String title = doc.title();

成功获取title :“yhao的博客- 博客频道 - CSDN.NET”,此处先进行请求,请求后的页面再交由Jsoup处理,其实Jsoup内部也集成了网络请求的功能,在翻阅源码时看到了HttpURLConnection的身影。

jsoup更多用法见:http://www.open-open.com/jsoup/

除了jsoup之外,java html解析工具还有htmlparser、JTidy、NekoHTML等,有兴趣可查阅:
http://www.oschina.net/project/tag/236/html-parser
http://renegade24.iteye.com/blog/865197

爬取动态页面

需求:获取本人博客页面的访问量

首先通过谷歌浏览器查看该页源代码,访问量片段如下:

......

<ul id="blog_rank">
    <li>访问:<span>43388次</span></li>
    <li>积分:<span>611</span> </li> 

......

但是通过get请求返回的页面并找不到这一片段

显而易见,访问量数据是通过ajax动态注入页面的

那么怎么抓取到ajax动态生成的内容呢?有以下两种方案:

  1. 捕获ajax请求url,发送该请求抓取

  2. 待页面加载完后再抓取

1.捕获ajax请求,通过谷歌浏览器F12 Network功能监控页面所有请求,其中最可疑的url:

http://lib.csdn.net/public/api/getUserStructList?callback=jQuery1111033149575415640986_1488528032250&_=1488528032251

然而获取的数据为:

jQuery1111033149575415640986_1488528032250({err: 0, msg: "ok", data: []})

尝试一下其他请求的url:

http://medal.blog.csdn.net/showblogmedal.ashx?blogid=5633873

返回的数据:

printMedal([{'src':'http://static.blog.csdn.net/images/medal/holdon_s2.gif','title':'持之以恒','desc':'授予每个自然月内发布4篇或4篇以上原创或翻译IT博文的用户。不积跬步无以至千里,不积小流无以成江海,程序人生的精彩需要坚持不懈地积累!','desc2':'6月份发表4篇原创/翻译文章','count':1}]);

即有的请求url可以获取,而一些敏感数据不能直接通过url请求获取。对于敏感数据就要用第二种方案,待页面加载完成后再爬取页面数据。

此时就要用到PhantomJS工具,PhantomJS是一个基于webkit的javascript API。它使用QtWebKit作为它核心浏览器的功能,使用webkit来编译解释执行JavaScript代码。

任何你可以在基于webkit浏览器做的事情,它都能做到,它不仅是个隐形的浏览器,除了浏览器外还有其他广泛的功能,感兴趣的可查阅:
http://www.codesec.net/view/206245.html

phantomjs使用步骤:
1. 下载:http://download.csdn.net/download/u013934914/9449600

2.编写js代码 :

code.js (与phantomjs.exe在统一目录):

system = require('system')  
address = system.args[1];
var page = require('webpage').create();  
var url = address;  
page.open(url, function (status) {  
    //Page is loaded!  
    if (status !== 'success') {  
        console.log('Unable to post!');  
    } else {  
        var encodings = ["euc-jp", "sjis", "utf8", "System","gb2312"];
        phantom.outputEncoding = encodings[4];
        console.log(page.content);
        phantom.exit();
    } 
  });

3.phantomjs命令运行js代码

在phantomjs.exe所在目录打开cmd,运行命令:

phantomjs code.js http://blog.csdn.net/yhaolpz?viewmode=contents

返回了页面ajax加载完后的所有内容,其中当然有我们需要的数据:

<ul id="blog_rank">
    <li>访问:<span>43399次</span></li>
    <li>积分:<span>611</span> </li>

4.java中调用

 public static String getAjaxContent(String url) throws Exception {
        Runtime rt = Runtime.getRuntime();
        Process p = rt.exec("C:/Users/asus/Downloads/phantomjs-2.1.1-windows/binphantomjs.exe C:/Users/asus/Downloads/phantomjs-2.1.1-windows/code.js " + url);
        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 + "\n");
        }
        return sbf.toString();
    }

以上为phantomjs在windows环境下的使用步骤,那么在Android中怎么爬取ajax页面内容呢?类似于phantomjs,Android中有没有一个隐形浏览器类的工具可以调用呢?先挖下坑…

猜你喜欢

转载自blog.csdn.net/yhaolpz/article/details/60087849