标签(空格分隔): 杂乱之地html
最近在作爬虫,主要是抓取淘宝商品的销量数据。在搜索页很容易就能抓到细览页的数据,主要问题难点是在抓取细览页中,页面的销量及评价数据是经过ajax来动态加载的。这一部分处理比较麻烦。同时又要解决屏蔽的问题。这几天一直在找解决访问。通常的爬虫都是不支持ajax数据的爬取的。写一下这几天作的各类工具的demo吧。
如今(2016年1月)市面上可以抓取ajax数据的主要有如下技术:htmlunit,casperjs,phantomjs,selenium.java
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; } } } }
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,因此就放弃了这种方法。web
selenium
selenium也是一个自动测试框架,属于有界面的,原理与上面的js是同样的。经过命令来肯定发送操做浏览器的指令。通过一翻实验发现,对于代理的操做相对来讲也不是很方便,并且属于有界面的,还不如使用chrome来开发插件的方式来解决这个问题。也方便非it人员调用。ajax
总结:
1.若是须要频繁抓取,目前的解决方案是chrome+插件来解决。
2.若是能解决htmlunit的代理问题。效果优于1.
3.htmlunit代理问题不局限于代理不上,还有对于socks支持的问题。chrome