几种网页爬取的方法与实现(Java)

一、通过HttpClient(apache commons-httpclient)方式,获许网页内容,并解析出需要的东西。

这种方法相对比较简单,因为commons-httpclient已经做了很好的封装,简单的代码如下:

  // 构造HttpClient的实例
  HttpClient httpClient = new HttpClient();
  HttpClientParams clientParams = new HttpClientParams();
  // 隐藏自己请求相关的信息
  clientParams.setParameter("http.useragent",
    "Mozilla/4.0 (compatible; FIREFOX 9.0; IBM AIX 5)");
  clientParams.setHttpElementCharset("GBK");
  HttpState httpState = new HttpState();
  httpClient.setParams(clientParams);
  httpClient.getParams().setParameter(
    HttpClientParams.HTTP_CONTENT_CHARSET, "GBK");
  httpClient.setState(httpState);
  clientParams.setVersion(HttpVersion.HTTP_1_1);
  if (useProxy) // 使用代理
  {
   httpClient.getHostConfiguration().setProxy(proxyIp, port);
  }



这里需要注意的是记得设置http.useragent属性,默认会显示为httpclient代理,很多网站为了防止被恶意爬取,最简单的方式就是判断useragent属性。

二、第一种方式最简单,但是也最容易被网站禁止掉,因为这种方式是不会执行javascript的,这样就很容易被网站通过javascript做标识识别出来,同时获取的数据如果是通过javascript计算来的,也会比较麻烦。

那么,我们来看第二种方式,通过模拟真正的browser来获取网页内容,并执行javascript,目前大部分流行的浏览器内核都是开放的,比如webkit,下面我们以mozilla引擎为例,实现如下:

首先,我们会用到xulrunner,这是使用mozilla引擎的xul浏览器,在这里我们用来替代mozilla实现。

下载xulrunner后,解压缩到相应目录

在代码中进行配置。

static {
Mozilla.getInstance().initialize(new File("D:\\xulrunner"));
System.setProperty("org.eclipse.swt.browser.XULRunnerPath",
"D:\\xulrunner");
}


将代码中的xulrunner目录位置修改为你解压缩的位置。

我们使用SWT来实现界面,SWT的Browser控件可以使用多个浏览器引擎,设置如下:

final Browser browser = new Browser(shell,
SWT.MOZILLA); // 1
nsIWebBrowser b = (nsIWebBrowser) browser.getWebBrowser();
browser.addProgressListener(new ProgressListener() {
public void changed(ProgressEvent arg0) {
}
public void completed(ProgressEvent event) {
if (listener != null) {
String html = (String) browser
.evaluate("return document.documentElement.innerHTML;");
try {
listener.onData(index,
(String) browser.getData(),
html);
} catch (Exception e) {
e.printStackTrace();
}
}
}
});


这里,我们通过执行一段javascript得到所有的html内容。

讲到这里,如果不是很频繁的访问,基本上已经满足需求了。但是如果访问太过频繁,一般网站都会很容易识别到,一种简单的方法就是不停的转换代理IP。代码如下:

public void setProxy(final int type,final String host,final int port){
nsIServiceManager serviceManager = Mozilla.getInstance().getServiceManager();
String contractID = "@mozilla.org/preferences-service;1";
nsIPrefService prefService = (nsIPrefService) serviceManager.getServiceByContractID(
contractID, nsIPrefService.NS_IPREFSERVICE_IID);
      // Get a branch to access to the entire preference tree
nsIPrefBranch branch = prefService.getBranch("");  //4
branch.setIntPref("network.proxy.type", type);
branch.setCharPref("network.proxy.http",host);  //5
branch.setIntPref("network.proxy.http_port",port);
}


网上有很多代理IP,大家可以去找找。

猜你喜欢

转载自jinshunlong.iteye.com/blog/1132148