摘要:将内容格式化作者第页第页内容爬取完毕。。。
前文链接 : java爬取捧腹网段子
上一篇文章讲述了如何使用Java爬取内容并写入文件,但是速度堪忧,今天将代码搞成了多线程版本,
具体方式如下:
新建一个splider类,继承callable接口,用于存放我们需要多线程执行的逻辑:
将上一篇文章中爬取网页内容的代码搬过来
public class Splider implements Callable { // 使用atomicInteger保证共享变量的安全自增 private AtomicInteger pageNum = new AtomicInteger(0); @Override public StringBuilder call() throws Exception { // 当前页码 Integer privateNum = this.pageNum.addAndGet(1); // 存储当前页的文本 StringBuilder currentPageText = new StringBuilder(); System.out.println("正在爬取第" + privateNum + "页内容。。。"); String html = ConnectionUtil.Connect("https://www.pengfu.com/xiaohua_" + privateNum + ".html"); Document doc = Jsoup.parse(html); Elements titles = doc.select("h1.dp-b"); for (Element titleEle : titles) { Element parent = titleEle.parent(); String title = titleEle.getElementsByTag("a").text(); String author = parent.select("p.user_name_list > a").text(); String content = parent.select("div.content-img").text(); // 将内容格式化 currentPageText.append(title) .append(" 作者:").append(author) .append(" ").append(content) .append(" ").append(" "); } currentPageText.append("-------------第").append(privateNum).append("页-------------").append(" "); System.out.println("第" + privateNum + "页内容爬取完毕。。。"); // 将当前页内容返回给future对象 return currentPageText; } }
主函数:
public static void main(String[] args) throws ExecutionException, InterruptedException { long startTime = System.currentTimeMillis(); // 创建大小为5的线程池 ExecutorService esPool = Executors.newFixedThreadPool(5); List> futureList = new ArrayList<>(); Splider splider = new Splider(); for (int i = 1; i <= 10; i++) { futureList.add(esPool.submit(splider)); } List finishCount = new ArrayList<>(); for (Future future : futureList) { // 线程结束,将线程返回的内容添加到list finishCount.add(future.get()); } /* * 所有内容爬取完毕,将内容统一写入磁盘 */ if (finishCount.size() == 10) { StringBuilder allText = new StringBuilder(); /* * finishCount中future.get()的顺序 和 futureList中的future顺序一致 * 所以内容是从第1页...第N页顺序写入 */ for (StringBuilder pageNum : finishCount) { allText.append(pageNum); } // 写入磁盘 Test.writeToFile(allText.toString()); long endTime = System.currentTimeMillis(); System.out.println("耗时 : " + (endTime - startTime)); // 关闭线程池 esPool.shutdownNow(); } }
执行结果:
查看本地文件,顺序和内容也都没有问题:
总结:
多个线程共享变量,只new一个实例,传给多个线程使用;
可以使用atomit类、synchronized、volitaile、lock保证多线程共享变量的安全性;
future.get()顺序和executorService.submit()顺序一致,和谁先执行完毕无关
使用callable + future可以获取线程返回值、捕获;
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/76671.html
摘要:引入的包用于解析开始分析网站捧腹网段子首先找到我们需要的内容作者标题和正文查看其元素,我这里查看的是标题标签知道其结构之后,就可以获取我们想要的内容了正在爬取第页内容。。。将内容写入磁盘参考文章爬虫入门一爬取糗百 先上效果图: showImg(https://segmentfault.com/img/bVbe5kf?w=1001&h=320); showImg(https://segm...
摘要:前提好几周没更新博客了,对不断支持我博客的童鞋们说声抱歉了。熟悉我的人都知道我写博客的时间比较早,而且坚持的时间也比较久,一直到现在也是一直保持着更新状态。 showImg(https://segmentfault.com/img/remote/1460000014076586?w=1920&h=1080); 前提 好几周没更新博客了,对不断支持我博客的童鞋们说声:抱歉了!。自己这段时...
摘要:通过本文的学习,可以快速掌握网络爬虫基础,结合实战练习,写出一些简单的爬虫项目。从技术手段来说,网络爬虫有多种实现方案,如。二网络爬虫技术基础在本次课中,将使用技术手段进行项目的编写。 摘要:本文详细讲解了python网络爬虫,并介绍抓包分析等技术,实战训练三个网络爬虫案例,并简单补充了常见的反爬策略与反爬攻克手段。通过本文的学习,可以快速掌握网络爬虫基础,结合实战练习,写出一些简单的...
摘要:学习网络爬虫主要分个大的版块抓取,分析,存储另外,比较常用的爬虫框架,这里最后也详细介绍一下。网络爬虫要做的,简单来说,就是实现浏览器的功能。 Python学习网络爬虫主要分3个大的版块:抓取,分析,存储 另外,比较常用的爬虫框架Scrapy,这里最后也详细介绍一下。 首先列举一下本人总结的相关文章,这些覆盖了入门网络爬虫需要的基本概念和技巧:宁哥的小站-网络爬虫,当我们在浏览器中输入...
摘要:时间永远都过得那么快,一晃从年注册,到现在已经过去了年那些被我藏在收藏夹吃灰的文章,已经太多了,是时候把他们整理一下了。那是因为收藏夹太乱,橡皮擦给设置私密了,不收拾不好看呀。 ...
阅读 3356·2021-11-04 16:10
阅读 3852·2021-09-29 09:43
阅读 2695·2021-09-24 10:24
阅读 3348·2021-09-01 10:46
阅读 2505·2019-08-30 15:54
阅读 588·2019-08-30 13:19
阅读 3234·2019-08-29 17:19
阅读 1053·2019-08-29 16:40