日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

网络爬虫:基于对象持久化实现爬虫现场快速还原

發布時間:2025/3/20 编程问答 16 豆豆
生活随笔 收集整理的這篇文章主要介紹了 网络爬虫:基于对象持久化实现爬虫现场快速还原 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前言:

? 因為中間有一些其他的任務工作,所以有一些時日沒有再關心爬蟲的程序了。今天想到了另一個優化爬蟲的思路。

? 在上篇中,我們說到可以使用布隆過濾器可以很好地實現URL的去重操作。可是,如果在某一個時刻我們不小心中止了爬蟲的繼續運行。這個時候要怎么辦呢?

? 本篇博客的重點正是解決這個問題。


本文鏈接:http://blog.csdn.net/lemon_tree12138/article/details/50069047 -- Coding-Naga
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?--轉載請注明出處


問題描述:

? 上面也有提到,現在假設我們的程序需要在中途暫停一下。這樣,會直接導致一個問題,我們的程序無法保留之前使用BloomFilter保存的URL信息。如果你對BloomFilter還不了解,歡迎移步到我的上一篇博客《網絡爬蟲:URL去重策略之布隆過濾器(BloomFilter)的使用》了解一下。

? 對于爬蟲程序中使用兩個隊列“對象”是好處理的,因為這部分數據是直接存放在數據庫中(磁盤里)的。這個不用擔心。可是如果這個BloomFilter如果沒有得到一個很好的處理就是一個比較麻煩的事情了,這使得我們在后期程序執行的過程中無法很準確地判斷一個URL是否有訪問過,這樣程序的效率勢必會受到不了的影響。這里我提供了兩種解決方案。當然一種是好的解決方法,一種是不那么好的解決方法。


前一種處理方案:

? 這里我想到的是如何通過現在有的數據(數據庫中的數據)信息,盡可能完整地構建原來的BloomFilter。我的做法是在程序重新啟動的時候去讀數據庫,把數據庫中的信息一個一個地往過濾器中填。試想一下,如果這個時候數據庫中有千萬級的數據,我們也要一個一個地往里填,這樣勢必有點太耗時了。

? 因為這里我們是需要先從數據庫中去獲得數據,再將數據添加到過濾器中。這兩步都是耗時的操作,所以,如果能不用這種方法就不用這種方法,這是下下策。


對象持久化方案:

1.格式化數據保存到文件

? 從之前的博客中,我們可以知道BloomFilter的核心是一個很長的數組,這個數組是保存在BitSet中。那么這里我們就可以把這么多位的每一位保存到文件或是數據庫中。這樣在程序啟動的時候就可以直接讀入了。關于這個想法,我猜是可行的。之所以說是“猜”,因為我也沒有使用過這樣方法。感覺是Ok的,不過沒實踐過,如果讀者感興趣可以試試看。這里就不多說了,說這個思路的目的,主要還是為了引出下面的這種方法。

2.基于Serializable的實現

思路分析:

? 說過了下下策和保存到文件這兩種,是不是這里可以說一下上上策了?因為還不知道有沒有更好的方法,所以上上策還不敢斷言,不過這里要說的可以說是上策。我們在學習可序列化類Serializable的時候,應該就已經知道了這個類可以讓一個對象固化到磁盤,也就是說這個對象我們可以把它保存到磁盤上。下次在需要用的時候再去讀一下就OK了。所以,這里我們就可以這樣來做。

? 首先,我們需要讓BloomFilter及其相關類實現Serializable接口,因為這些對象需要被持久化。并且添加上serialVersionUID成員常量。

保存到磁盤:

/*** 將一個對象寫入到磁盤* * @param s* 待寫入的對象* @param path* 寫入的路徑*/public static void writeObject(Serializable s, String path) {try {ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream(path));objectOutputStream.writeObject(s);objectOutputStream.close();} catch (IOException e) {e.printStackTrace();}}

從磁盤中讀取對象:

public static Object readObject(String path) {Object object = null;try {ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream(path));object = objectInputStream.readObject();objectInputStream.close();} catch (IOException e) {e.printStackTrace();} catch (ClassNotFoundException e) {e.printStackTrace();}return object;}

測試過程:

? 測試的方法很簡單,我們先在過濾中添加一些數據。并將持有數據的過濾器對象寫到磁盤中。在我們需要的時候去讀取磁盤上保存的對應文件即可。代碼邏輯如下:

public class BloomFilterTest {public static void main(String[] args) {String path = "F:/Temp/bloom.obj";BloomFilterTest test = new BloomFilterTest();test.testWriteBloomFilter(path);BloomFilter readFilter = test.testReadBloomFilter(path);boolean b1 = readFilter.contains("baidu");boolean b2 = readFilter.contains("google");boolean b3 = readFilter.contains("naga");boolean b4 = readFilter.contains("hello");boolean b5 = readFilter.contains("world");boolean b6 = readFilter.contains("java");System.out.println(b1);System.out.println(b2);System.out.println(b3);System.out.println(b4);System.out.println(b5);System.out.println(b6);}private void testWriteBloomFilter(String path) {BloomFilter filter = new BloomFilter();filter.add("baidu");filter.add("google");filter.add("naga");filter.add("hello");filter.add("world");SerializationUtils.writeObject(filter, path);}private BloomFilter testReadBloomFilter(String path) {Object object = SerializationUtils.readObject(path);return (BloomFilter)object;} }

測試結果:

? 我們在過濾器中添加了"baidu",?"google",?"naga",?"hello",?"world"這些字符串值。在驗證的時候,我們多驗證了一個"java"字符串。如果方案可行,我們將獲得5個true和1個false的結果。以下是測試結果:
true true true true true false 由此驗證此方法可行。

注意事項:

? 1.過濾器內部的SimpleHash內部類也需要實現Serializable接口。因為這個SimpleHash也有對象在過濾器中,在持久化的時候,SimpleHash對象也會被持久化到磁盤;

? 2.本文的測試實例,可以在下面GitHub工程的org.naga.demo.bloom包下獲得;

? 3.本方案的作用點是在于停止程序的后勤工作。所以,必須保證程序能夠完成這些后勤工作。也就是說,我們不能突然去停止程序的運行,這樣程序因為來不及保存數據而讓BloomFilter對象持久化失敗。如果想要規避這個問題,就必須要作出一些其他的犧牲——性能下降。我們可以通過定時給BloomFilter進行持久化,這樣如果程序被突然中止,也只是會損失一部分數據的記錄,不會造成很大的影響。因為,這樣會是程序的性能有所下降,所以如何取舍還是要看需求了。


測試源碼工程GitHub鏈接:

https://github.com/William-Hai/SimpleDemo

總結

以上是生活随笔為你收集整理的网络爬虫:基于对象持久化实现爬虫现场快速还原的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。