Htmlunit 添加接口方法->拦截获取下载链接
htmlunit是一款很不错的爬虫工具,它可以模拟不同浏览器进行网页的请求,然后进行页面数据的爬取,根据你选择的浏览器,会有不同的爬虫效果和速度的差异,而且还能获取到下载链接。
在此处要讨论的是htmlunit爬取酷安时,虽能获取APP的下载链接,但却是酷安的认证链接(会失效),在请求认证链接后,进行重定向后才能获取最终的链接,然而,在重新请求时,因为时下载链接,故会进行下载文件,最终才会返回请求结果(真实的下载链接)。
由于此过程会进行下载文件,故爬取速度非常慢,因此想到在htmlunit中添加一个接口到请求的链接中,当发现是最终的请求链接时,则记录此链接,并终止此请求的处理,从而实现快速获取下载链接。
0.准备htmlunit源码并导入Eclipse
下载链接(教程选择版本2.29,以maven3.5.2版导入成功):
https://sourceforge.net/projects/htmlunit/files/htmlunit/
1.添加拦截接口
定位到WebClient.java
文件[com.gargoylesoftware.htmlunit.WebClient
]中。
添加如下接口方法:
/**
* 需要匹配的链接组
*/
private static ConcurrentHashMap<String, MatchHref> needMatchHrefMap=new ConcurrentHashMap<String, MatchHref>();
/**
* @param origionUrl 原始的链接
* @param matchHref 需要匹配的链接
*/
public static void RegisterListenHref(String origionUrl,MatchHref matchHref){
if (matchHref!=null&&!needMatchHrefMap.containsKey(origionUrl)) {
needMatchHrefMap.put(origionUrl, matchHref);
}
}
/**
* 匹配新的链接,提供接口给用户自定义
* 当有url符合要求时结束任务
*/
public interface MatchHref{
/** 判断该链接是否符合要求
* @param url 链接
* @return 是否符合
*/
public boolean isMatched(String url);
}
将接口方法添加到的
loadWebResponseFromWebConnection
方法中调用,
直接搜索定位到此处::
newUrl = expandUrl(url, locationString);
在其前面添加如下接口方法:
//-----额外部分
String fromUrl=null;
try {
fromUrl=webResponse.getWebRequest().getAdditionalHeaders().get("Referer");
} catch (Exception e) {
System.out.println("获取来源Url错误"+e.getMessage());
}
if (fromUrl!=null&&!fromUrl.isEmpty()) {
boolean qualify = needMatchHrefMap.get(fromUrl).isMatched(locationString);
if (qualify) {//当符合时结束后续进程
needMatchHrefMap.remove(fromUrl);
throw new MalformedURLException("获取到下载链接:downUrl=["+locationString+"]");
}
}
//------结束
newUrl = expandUrl(url, locationString);
2.测试
新建一个test.java文件,然后添加如下内容:
public static void main(String[] args) {
System.out.println("Hello World!");
try {
Crawler("https://www.coolapk.com/apk/com.kingsoft.calendar");
Crawler("https://www.coolapk.com/apk/tv.danmaku.bili");
} catch (Exception e) {
e.printStackTrace();
}
}
private static String urlResult;
public static String Crawler(String url) {
WebClient client = new WebClient(BrowserVersion.CHROME);
try {
client.getOptions().setUseInsecureSSL(true);
client.getOptions().setCssEnabled(false);
HtmlPage page = client.getPage(url);
// 定位下载按钮位置(酷安改版过一个次,所以请按情况找到Xpath并替换)
List<Object> byXPath = page.getByXPath("//button[@class='apk_topbar_btn']");
HtmlButton object = (HtmlButton) byXPath.get(0);
WebClient.RegisterListenHref(url,new MatchHref() {
// 实现监听
@Override
public boolean isMatched(String url) {
if (!url.contains(".coolapk.com")&&!url.contains("url=") && url.contains(".apk")) {
urlResult = url;
return true;
}
return false;
}
});
Page pageNew = object.click();
} catch (Exception e) {
System.out.println("获取的下载链接:" + urlResult);
client.close();
return urlResult;
}
return urlResult;
}
运行结果如下: