摘要:將內容格式化作者第頁第頁內容爬取完畢。。。
前文鏈接 : 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可以獲取線程返回值、捕獲;
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/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,這里最后也詳細介紹一下。 首先列舉一下本人總結的相關文章,這些覆蓋了入門網絡爬蟲需要的基本概念和技巧:寧哥的小站-網絡爬蟲,當我們在瀏覽器中輸入...
摘要:時間永遠都過得那么快,一晃從年注冊,到現在已經過去了年那些被我藏在收藏夾吃灰的文章,已經太多了,是時候把他們整理一下了。那是因為收藏夾太亂,橡皮擦給設置私密了,不收拾不好看呀。 ...
閱讀 3350·2021-11-04 16:10
閱讀 3846·2021-09-29 09:43
閱讀 2692·2021-09-24 10:24
閱讀 3338·2021-09-01 10:46
閱讀 2503·2019-08-30 15:54
閱讀 585·2019-08-30 13:19
閱讀 3232·2019-08-29 17:19
閱讀 1049·2019-08-29 16:40