[原创]一款基于Reactor线程模型的java网络爬虫框架
AJSpridergithub: https://github.com/zhuchangwu/AJSpider 概述AJSprider是笔者基于Reactor线程模式+Jsoup+HttpClient封装的一款轻量级java多线程网络爬虫框架,简单上手,小白也能玩爬虫, 本项目仅供学习使用,禁止任何人用它非法盈利 坐标<repositories> <repository> <id>jitpack.io</id> <url>https://jitpack.io</url> </repository> </repositories> <dependency> <groupId>com.github.zhuchangwu</groupId> <artifactId>AJSpider</artifactId> <version>1.0.0.SNAPSHOT</version> </dependency> 使用说明使用方法简单的没商量,三步打完收工
ok,现在进行第二步,重写 解析:
protected abstract SpiderSingleThreadExecutor<T>.SpiderContainer<T> resolution1(String var1,SpiderSingleThreadExecutor<T>.SpiderContainer<T> var2,SpiderResolutionUtil var3); 解析拓展:如果用户存在二级任务,需要用户重写
protected SpiderSingleThreadExecutor<T>.SpiderContainer<T> resolution2(String[] htmls,SpiderSingleThreadExecutor<T>.SpiderContainer<T> spiderContainer,SpiderResolutionUtil util) { } 持久化
public abstract void persistence(List<T> var1,PersistenceUtil<T> var2); 启动爬虫创建启动器对象
new SpiderBootStrap() .setTaskUrlQueue(taskQueue) .initThreadExcutorGroup(1,MyExecutor.class) .build(); 完整Demo-拉取新闻快捷键F12,观察需要爬取的网页的源码,DIY解析过程(使用提供的辅助类基础的解析都ok,当然你是一个正则大牛,按自己的解析方式也很好) public class MyThreadExcutor extends SpiderSingleThreadExecutor<News> { protected SpiderContainer<News> resolution1(String s,SpiderContainer<News> spiderContainer,SpiderResolutionUtil spiderResolutionUtil) { // 观察上图,我需要的新闻信息在一个id为wp_news_w6的div下 // 选择如下方法,根据id以及标签名获取出li的数组 String[] lis = spiderResolutionUtil.getElementsByIdAndTaggetName(s,"wp_news_w6","ul","li"); // 大家一定要注意,解析的步骤是一遍遍历上面的数组,一遍解析它,每次循环都创建一个新的对象盛放解析出来的字段 for (int i = 0; i < lis.length; i++) { String html = lis[i]; News qluNew = new News(); // 使用工具方法,把用户提供的 前后缀 之间的值取出来 // 注意了,这里的前后缀一定得是先把源码输出到控制台,再复制过来 String title = spiderResolutionUtil.getValueByPrefixSuffix(html,"">","</a></span> <span class="); String time = spiderResolutionUtil.getValueByPrefixSuffix(html,"<span class="news_meta">","</span> </li>"); String url1 = spiderResolutionUtil.getValueByPrefixSuffix(html,"class="news_title"><a href="","" target="_blank""); // 将解析出来的值存放在用户创建出来的对象中 qluNew.setTitle(title); qluNew.setDate(time); // 大家可以看到上面的图片,只用标题,时间,新闻体在二级url中,需要用户在这里完成拼接 String perfix = "http://www.qlu.edu.cn"; String targetUrl = perfix + url1; // 推荐大家在解析拼接二级url时多加几层判断,保证二级url的正确性 // 我们学校的新闻模块,就存在使用中不同的url的现象,拼接出来的效果是这个样"http://www.qlu.edu.cnhttp://2019sdh.qlu.edu.cn/2019/0305/c7334a122472/page.htm"; // 当时也挺蒙的,不过在700条新闻中,大概存在5条 // 我的处理是直接跳过这个url,如果不处理,框架根据错误的url下载,解析就终止了 if (targetUrl.substring(5,targetUrl.length()).contains("http:")) { // 说明上面的url拼接从新处理这个 url // url不同很大程度上意味着 resolution2() 按照不同的模板解析 continue; } //最后,别忘了创建的bean添加的容器中,往后传播 // 第一步 spiderContainer.getBeanList().add(qluNew); // 第二步 spiderContainer.getUrlList().add(perfix + url1); } // 返回容器 return spiderContainer; }
@Override protected SpiderContainer<News> resolution2(String[] htmltxt,SpiderResolutionUtil util) { // 遍历入参1中的下载好了的源码,从新解析出新闻体的新的字段放入容器中的bean集合 for (int i = 0; i < htmltxt.length; i++) { String body = util.getFirstElementValueByClass(htmltxt[i],"wp_articlecontent"); spiderContainer.getBeanList().get(i).setBody(body); } for (News news : spiderContainer.getBeanList()) { System.out.println("Thread.name = "+Thread.currentThread().getName()+news); } // 返回容器 return spiderContainer; } 持久化,用户根据自己的需求,选择如何持久化,list中存放的是前面用户解析出来的bean的集合 // persistenceUtil可以持久化图片到本地,前提是bean中仅有一个图片的url字段 public void persistence(List<News> list,PersistenceUtil<News> persistenceUtil) { } } 启动: public static void main(String[] args) { // 创建任务队列,任意队列都可以,不要求线程安全 LinkedBlockingQueue<String> taskQueue = new LinkedBlockingQueue(); // 假设在准备任务 String url ="http://www.qlu.edu.cn/38/list.htm"; taskQueue.offer(url); for (int i=2;i<50;i++){ String url2 = "http://www.qlu.edu.cn/38/list"+i+".htm"; taskQueue.offer(url2); } SpiderBootStrap spiderBootStrap = new SpiderBootStrap(); spiderBootStrap .initThreadExcutorGroup(10,MyThreadExcutor.class) .setTaskUrlQueue(taskQueue) .build(); } 重要的事情说三遍使用工具方法,需要的 前后缀 是需要从编译器的控制台复制过来的,直接赋值网页上的无效 使用工具方法,需要的 前后缀 是需要从编译器的控制台复制过的,直接赋值网页上的无效 笔者水平有限,请大佬批评指教!,有任何issue请联系笔者,如果您觉得还不错,欢迎star (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |