最近做的爬虫一些事

最近做的爬虫一些事

标签(空格分隔): 杂乱之地


最近在做爬虫,主要是抓取淘宝商品的销量数据。在搜索页很容易就能抓到细览页的数据,主要问题难点是在抓取细览页中,页面的销量及评价数据是通过ajax来动态加载的。这一部分处理比较麻烦。同时又要解决屏蔽的问题。这几天一直在找解决访问。一般的爬虫都是不支持ajax数据的爬取的。写一下这几天做的各种工具的demo吧。
现在(2016年1月)市面上能够抓取ajax数据的主要有以下技术:htmlunit,casperjs,phantomjs,selenium.

htmlunit

  • 代码
package com.kis;

import com.gargoylesoftware.htmlunit.*;
import com.gargoylesoftware.htmlunit.html.*;

import java.io.IOException;
import java.net.URL;
import java.util.Properties;

/**
 * Created by wanglong on 16-1-21.
 */
public class TestProxy {
    public static void main(String[] args) throws IOException {
        String url = "https://item.taobao.com/item.htm?id=520081147502&ns=1&abbucket=11#detail";
        WebClient webClient = new WebClient(BrowserVersion.FIREFOX_38);//设置浏览器的User-Agent
        webClient.setJavaScriptTimeout(100000);//设置JS执行的超时时间
        webClient.getOptions().setThrowExceptionOnScriptError(false);//当JS执行出错的时候是否抛出异常
        webClient.getOptions().setRedirectEnabled(true);
        webClient.getOptions().setThrowExceptionOnFailingStatusCode(false);//当HTTP的状态非200时是否抛出异常
        webClient.getOptions().setTimeout(30000);//设置“浏览器”的请求超时时间
        webClient.getOptions().setCssEnabled(false);//是否启用CSS
        webClient.getOptions().setJavaScriptEnabled(true); //很重要,启用JS
        webClient.waitForBackgroundJavaScript(100000);//设置JS后台等待执行时间
        webClient.getOptions().setThrowExceptionOnScriptError(false);
        webClient.setAjaxController(new NicelyResynchronizingAjaxController());//设置支持AJAX
        HtmlPage resultPage = webClient.getPage(url);
        HtmlStrong strong;
        webClient.waitForBackgroundJavaScript(2000);
        Long start = System.currentTimeMillis();
        for (int i = 0; i < 20; i++) {
            strong = resultPage.getFirstByXPath("//*[@id=\"J_SellCounter\"]");
            if (strong.asText().equals("-")) {
                webClient.waitForBackgroundJavaScript(1000);
            } else {
                Long end = System.currentTimeMillis();
                System.out.println(strong.asText());
                System.out.print("  所用时间为" + (end - start) / 1000 + "秒");
                break;
            }
        }
    }
}

  • 通过htmlunit可以获得到销量数据。但是由于要解决屏蔽及效率问题(多线程),所以肯定要使用代理的,但是我机器上设置代理不起作用不知道为什么,所以放弃了使用htmlunit
        Properties prop = System.getProperties();
        prop.setProperty("proxySet", "true");
        prop.setProperty("http.proxyHost", "61.191.27.117");
        prop.setProperty("http.proxyPort", "443");
        WebRequest webRequest = new WebRequest(new URL(url));
        webRequest.setProxyHost("202.103.241.169");
        webRequest.setProxyPort(1080);
        webRequest.setSocksProxy(true);
  • 通过以上两种方式设置的代理都不管用,通过访问www.ip138.com获得的ip还是我本机的ip,所以就放弃了这种方法。

js

  • casperjs&phantomjs
    这两个都是js的自动测试框架。通过js来模拟点击浏览器操作,属于无界面的浏览器。通过实验发现也是可以并且很轻松的能够获得通过ajax加载的数据。但是只能通过shell命令来输入代理。所以这种方式最后也是放弃了。
  • selenium
    selenium也是一个自动测试框架,属于有界面的,原理与上面的js是一样的。通过命令来确定发送操作浏览器的指令。经过一翻实验发现,对于代理的操作相对来说也不是很方便,而且属于有界面的,还不如使用chrome来开发插件的方式来解决这个问题。也方便非it人员调用。

总结:
1.如果需要频繁抓取,目前的解决方案是chrome+插件来解决。
2.如果能解决htmlunit的代理问题。效果优于1.
3.htmlunit代理问题不局限于代理不上,还有对于socks支持的问题。

posted @ 2016-01-30 16:40  宁静致远_  阅读(3242)  评论(0编辑  收藏  举报