分享一个简单的java爬虫框架
反复给网站编写不同的爬虫逻辑太麻烦了,自己实现了一个小框架
可以自定义的部分有:
请求方式(默认为Getuser-agent为谷歌浏览器的设置),可以通过实现RequestSet接口来自定义请求方式
储存方式(默认储存在f盘的html文件夹下),可以通过SaveUtil接口来自定义保存方式
需要保存的资源(默认为整个html页面)
筛选方式(默认所有url都符合要求),通过实现ResourseChooser接口来自定义需要保存的url和资源页面
实现的部分有:
html页面的下载方式,通过HttpClient实现html页面的下载
html页面的解析部分,通过jsoup实现html页面的解析
HtmlDownloader类,用于根据一个url下载一个html页面
packageDownloadPackage;
importjava.io.BufferedReader;
importjava.io.IOException;
importjava.io.InputStreamReader;
importorg.apache.http.HttpEntity;
importorg.apache.http.HttpResponse;
importorg.apache.http.impl.client.CloseableHttpClient;
importorg.apache.http.impl.client.HttpClients;
/*
*根据一个url下载一个html页面
*/
publicclassHtmlDownloader{
RequestSetrequestset=null;
publicHtmlDownloader(RequestSetrequestset){
this.requestset=requestset;
}
publicStringdownloadhtml(Stringurl){
Stringhtml=null;
//创建一个客户端
//创建一个读取流从entity读取html
BufferedReaderreader=null;
CloseableHttpClienthttpclient=HttpClients.createDefault();
HttpResponseresponse=null;
try{
response=httpclient.execute(requestset.getMethod(url));
HttpEntityentity=response.getEntity();
reader=newBufferedReader(newInputStreamReader(entity.getContent()));
StringBuildersb=newStringBuilder();
while((html=reader.readLine())!=null){
sb.append(html);
}
html=sb.toString();
System.out.println("一个html页面获取成功");
}
catch(IOExceptione){
System.out.println(url+"连接失败");
}
finally{
if(reader!=null){
try{
reader.close();
httpclient.close();
}
catch(IOExceptione){
//TODOAuto-generatedcatchblock
e.printStackTrace();
}
}
}
returnhtml;
}
}
UrlGet类,用于根据一个html页面获得所有的url连接
packageDownloadPackage;
importjava.util.LinkedList;
importorg.jsoup.Jsoup;
importorg.jsoup.nodes.Document;
importorg.jsoup.nodes.Element;
importorg.jsoup.select.Elements;
publicclassUrlGet{
publicLinkedListgeturls(Stringhtml){
LinkedListurls=newLinkedList();
Documentdoc=Jsoup.parse(html);
Elementslinks=doc.getElementsByTag("a");
for(Elementlink:links){
Stringurl=link.attr("href");
urls.add(url);
}
returnurls;
}
}
资源选择接口,需要实现三个方法,第一是isNeed方法,判断url是否为需要的,第二个是isResourse方法,判断url页面是不是需要的资源页面,第三个是process方法,
有时网页上的url是我们需要的但是格式不对,对url进行加工
packageChoosePackage;
publicinterfaceResourseChooser{
publicBooleanisNeed(Stringurl);
publicBooleanisResourse(Stringurl);
publicStringprocess(Stringurl);
}
RequsetSet类,用于自定义请求方法的接口,实现getMethod方法获取请求方法
packageDownloadPackage;
importorg.apache.http.client.methods.HttpGet;
/*
*一个用于获得Request请求的接口
*实现getMethod方法获取Get方法
*/
publicinterfaceRequestSet{
publicHttpGetgetMethod(Stringurl);
}
Saveutil接口用于自定义保存方式,需要实现save方法
packageSaveUtil;
/*
*数据储存的工具接口,必须实现保存方法
*/
publicinterfaceSaveUtil{
publicvoidsave(Stringurl,Stringhtml);
}
Spider类,有五中构造方法,可以实现多种自定义操作,其中实现了上述自定义接口的默认实现类
packageSpider;
importjava.io.BufferedWriter;
importjava.io.File;
importjava.io.FileWriter;
importjava.io.IOException;
importjava.util.HashSet;
importjava.util.Iterator;
importjava.util.LinkedList;
importorg.apache.http.client.config.RequestConfig;
importorg.apache.http.client.methods.HttpGet;
importChoosePackage.MyResourseChooser;
importChoosePackage.ResourseChooser;
importDownloadPackage.HtmlDownloader;
importDownloadPackage.RequestSet;
importDownloadPackage.UrlGet;
importSaveUtil.MySaveUtil;
importSaveUtil.SaveUtil;
/*
*用于爬取资源的类
*/
publicclassSpider{
publicstaticvoidmain(String[]args){
newSpider("http://www.bilibili.net").spiderstart();
}
//种子url
Stringseed=null;
//用于保存数据的类,需要自己实现
privateSaveUtilsaveutil=null;
//html下载类
privateHtmlDownloaderdownloader=null;
//url下载类
privateUrlGeturldownloader=null;
//资源选择工具
privateResourseChooserresoursechooser=null;
//用于保存未下载的网页
LinkedListunvisited=newLinkedList();
//用于保存已下载的网页
HashSetvisited=newHashSet();
//自定义储存方式,请求方式,资源筛选方式的构造方法
publicSpider(SaveUtilsaveutil,RequestSetrequest,ResourseChooserresoursechooser,Stringseed){
this.saveutil=saveutil;
this.downloader=newHtmlDownloader(request);
this.urldownloader=newUrlGet();
this.resoursechooser=resoursechooser;
this.seed=seed;
unvisited.add(seed);
}
//自定义储存方式,资源筛选方式的构造方法
publicSpider(SaveUtilsaveutil,ResourseChooserresoursechooser,Stringseed){
this.resoursechooser=resoursechooser;
this.downloader=newHtmlDownloader(newgetRequest());
this.saveutil=saveutil;
this.urldownloader=newUrlGet();
this.seed=seed;
unvisited.add(seed);
}
//自定义储存方式,请求的构造方法
publicSpider(SaveUtilsaveutil,RequestSetrequestset,Stringseed){
this.saveutil=saveutil;
this.downloader=newHtmlDownloader(requestset);
this.resoursechooser=newMyResourseChooser();
this.urldownloader=newUrlGet();
this.seed=seed;
unvisited.add(seed);
}
//自定义储存方式的构造方法
publicSpider(SaveUtilsaveutil,Stringseed){
this.saveutil=saveutil;
this.downloader=newHtmlDownloader(newgetRequest());
this.resoursechooser=(newMyResourseChooser());
this.urldownloader=newUrlGet();
this.seed=seed;
unvisited.add(seed);
}
//默认的爬虫构造方法
publicSpider(Stringseed){
this.saveutil=newMySaveUtil();
this.downloader=newHtmlDownloader(newgetRequest());
this.resoursechooser=(newMyResourseChooser());
this.urldownloader=newUrlGet();
this.seed=seed;
unvisited.add(seed);
}
//开始爬取的方法
privatevoidspiderstart(){
Stringhtml=null;
while(!unvisited.isEmpty()){
Stringurl=unvisited.poll();
System.out.println("开始获取"+url);
if(resoursechooser.isNeed(url)){
try{
html=downloader.downloadhtml(url);
}
catch(RuntimeExceptione){
System.out.println(url+"连接获取失败");
continue;
}
visited.add(url);
LinkedListurls=newLinkedList();
try{
urls=urldownloader.geturls(html);
}
catch(RuntimeExceptione){
System.out.println(url+"的html页面为空");
continue;
}
Iteratorit=urls.iterator();
while(it.hasNext()){
Stringnewurl=it.next();
if(resoursechooser.isNeed(newurl)&&!visited.contains(newurl)&&!unvisited.contains(newurl)){
newurl=resoursechooser.process(newurl);
unvisited.add(newurl);
System.out.println(newurl+"加入页面");
}
}
System.out.println("获取了"+url+"上的所有url");
if(resoursechooser.isResourse(url)){
saveutil.save(url,html);
}
}
}
}
//默认资源筛选类
privateclassMyResourseChooserimplementsResourseChooser{
@Override
publicBooleanisNeed(Stringurl){
//TODOAuto-generatedmethodstub
if(!url.startsWith("/")&&!url.startsWith("http")){
returnfalse;
}
returntrue;
}
@Override
publicBooleanisResourse(Stringurl){
//TODOAuto-generatedmethodstub
returntrue;
}
@Override
publicStringprocess(Stringurl){
//TODOAuto-generatedmethodstub
if(!url.startsWith("http")){
url=seed+url;
}
returnurl;
}
}
publicclassgetRequestimplementsRequestSet{
publicHttpGetgetMethod(Stringurl){
//TODOAuto-generatedmethodstub
//创建一个get请求方法
HttpGetgetmethod=newHttpGet(url);
//HttpHostproxy=newHttpHost("124.88.67.81",80);这里不设置代理IP
//设置请求超时时间等
RequestConfigresponseconfig=RequestConfig.custom().setConnectionRequestTimeout(10000).setConnectTimeout(10000).setSocketTimeout(10000).build();
//设置请求头,主要是user-agent
getmethod.addHeader("User-Agent","Mozilla/5.0(WindowsNT10.0;WOW64)AppleWebKit/537.36(KHTML,likeGecko)Chrome/56.0.2924.87Safari/537.36");
//设置请求参数
getmethod.setConfig(responseconfig);
returngetmethod;
}
}
//默认的存储类
publicclassMySaveUtilimplementsSaveUtil{
@Override
publicvoidsave(Stringurl,Stringhtml){
//TODOAuto-generatedmethodstub
Stringfilename=getfilename(url);
BufferedWriterwriter=null;
try{
writer=newBufferedWriter(newFileWriter(filename));
writer.write(html);
writer.flush();
System.out.println("文件写入成功");
}
catch(IOExceptione){
System.out.println("文件写入失败");
}
finally{
try{
if(writer!=null)
writer.close();
}
catch(IOExceptione){
//TODOAuto-generatedcatchblock
System.out.println("流关闭失败");
}
}
}
privateStringgetfilename(Stringurl){
Stringfileparentpath="f://html";
Filefile=newFile(fileparentpath);
if(!file.exists()){
file.mkdir();
}
intlast=url.lastIndexOf(".");
intfirst=url.indexOf(".");
url=url.substring(first,last);
url=url.replaceAll("\\.","");
url=url.replaceAll("/","");
returnfileparentpath+"/"+url+".txt";
}
}
}
总结
以上就是本文关于分享一个简单的java爬虫框架的全部内容,希望对大家有所帮助。感兴趣的朋友可以继续参阅本站:Python爬虫实例爬取网站搞笑段子、Java线程之锁对象Lock-同步问题更完美的处理方式代码实例、Java编程几个循环实例代码分享等,有什么问题可以随时留言,小编会及时回复大家的。感谢朋友们对本站的支持!