1. 程式人生 > >Scrapy-redis增量爬取以及Simhash相似文件的去重

Scrapy-redis增量爬取以及Simhash相似文件的去重

最近在實習,第一個任務就是從各大入口網站抓取新聞,爬蟲本身不是一個很難的事情,用scrapy框架很容易完成(關於scrapy的具體用法可以參考我之前的一篇部落格http://blog.csdn.net/john_xyz/article/details/78157805, 但是由於要求是要增量爬取,而且要去除相似的新聞,這裡記錄一下解決問題的方法以及踩過的坑

Scrapy-redis增量爬取

Scrapy-redis是在Scrapy的的基礎上,提供了一些一redis為基礎的元件。具體的,提供了Schedule, Dupefilter, Pipeline, Spider。有興趣的同學可以看看原始碼 darkrho/scrapy-redis · GitHub 。
Scrapy在爬取的過程當中,有一個主要的資料結構是“待爬佇列”,用python自帶的collection.deque來儲存,以及能夠操作這個佇列的排程器。
Scrapy-redis把deque換成redis資料庫。因為爬蟲程式需要每天定時爬取,因此,在redis中,每個網站(key)都有個判重池(dupefilter),該判重池儲存這爬取過的url。這樣在爬取的時候,當待抓取的url在判重池裡的時候,就不去抓新聞了,否則,就抓取新聞,並將url加入判重池.

Simhash相似文件的去重

Simhash(http://www2007.org/papers/paper215.pdf)是google在2007年提出的海量文字去重演算法。其核心思想是將一篇文件轉換成64位的位元,判斷文件是否相似就是判斷它們最後64位位元海明距離是否小於k(k一般取3),就可以判斷兩篇文件是否相似。需要說明的是Simhash是區域性敏感雜湊,也就是說,相似的文件或單詞,其雜湊值也是相似的
這裡寫圖片描述
演算法流程:
1. 對Doc進行關鍵詞抽取(分詞和計算TF-IDF權重),抽出n個關鍵詞[(wod1, weight1), (word2, weight2), …,(wordn, weightn)]
2. 對每個word,計算雜湊值 hash_weight_pairs = [(hash(word1), weight), (hash(word2), weight2),…, (hash(wordn), weightn)],每個單詞被hash成預設64位的二進位制位元。
3. 對hash_weight_pairs進行縱向加權求和,如果該位是1,則+weight,如果是0,則-weight,最後生成長度位64的陣列
4.遍歷這64位的陣列,如果該位為正,則轉換成1,否則位0

海明距離的計算

舉個簡單例子來說明

A = [1,0,0,1,1,1]
b = [1,0,0,1,1,0]

A和B的海明距離是1,就是A xor B後二進位制1的個數。
實際在做去重時,一般取k=3, 也就是海明距離小於3,認為兩篇文件相似

演算法的幾何意義和原理

隨機超平面hash演算法

Simhash是由隨機超平面hash演算法演變而來的,隨機超平面hash演算法非常簡單,對於一個n維向量v,要得到一個f位的簽名(f << n),演算法如下:

1,隨機產生f個n維的向量r1,…rf;
2,對每一個向量ri,如果v與ri的點積大於0,則最終簽名的第i位為1,否則為0.

這個演算法相當於隨機產生了f個n維超平面,每個超平面將向量v所在的空間一分為二,v在這個超平面上方則得到一個1,否則得到一個0,然後將得到的f個0或1組合起來成為一個f維的簽名

Simhash演算法和隨機超平面hash演算法之間的聯絡

Simhash演算法與隨機超平面hash是怎麼聯絡起來的呢?在simhash演算法中,並沒有直接產生用於分割空間的隨機向量,而是間接產生的:第 k個特徵的hash簽名的第i位拿出來,如果為0,則改為-1,如果為1則不變,作為第i個隨機向量的第k維。由於hash簽名是f位的,因此這樣能產生 f個隨機向量,對應f個隨機超平面。下面舉個例子:

假設用5個特徵w1,…,w5來表示所有文件,現要得到任意文件的一個3維簽名。假設這5個特徵對應的3維向量分別為:

h(w1) = (1, -1, 1)T
h(w2) = (-1, 1, 1)T
h(w3) = (1, -1, -1)T
h(w4) = (-1, -1, 1)T
h(w5) = (1, 1, -1)T

按simhash演算法,要得到一個文件向量d=(w1=1, w2=2, w3=0, w4=3, w5=0) T的簽名,
先要計算向量m = 1*h(w1) + 2*h(w2) + 0*h(w3) + 3*h(w4) + 0*h(w5) = (-4, -2, 6) T,然後根據simhash演算法,得到最終的簽名s=001。
上面的計算步驟其實相當於,先得到3個5維的向量,第1個向量由h(w1),…,h(w5)的第1維組成:
r1=(1,-1,1,-1,1) T;
第2個5維向量由h(w1),…,h(w5)的第2維組成:
r2=(-1,1,-1,-1,1) T;
同理,第3個5維向量為:
r3=(1,1,-1,1,-1) T.

按隨機超平面演算法的步驟2,分別求向量d與r1,r2,r3的點積:
d * r1=-4 < 0,所以s1=0;
d * r2=-2 < 0,所以s2=0;
d * r3=6 > 0,所以s3=1.

故最終的簽名s=001,與simhash演算法產生的結果是一致的。

從上面的計算過程可以看出,simhash演算法其實與隨機超平面hash演算法是相同的,simhash演算法得到的兩個簽名的漢明距離,可以用來衡量原始向量的夾角。這其實是一種降維技術,將高維的向量用較低維度的簽名來表徵。衡量兩個內容相似度,需要計算漢明距離,這對給定簽名查詢相似內容的應用來說帶來了一些計算上的困難;我想,是否存在更為理想的simhash演算法,原始內容的差異度,可以直接由簽名值的代數差來表示呢?

利用Simhash進行海量文字的去重

使用上述方法產生的simhash可以用來比較兩個文字之間的相似度。問題是,如何將其擴充套件到海量資料的近重複檢測中去呢?譬如說對於64位的待查詢文字的simhash code來說,如何在海量的樣本庫(>1M)中查詢與其海明距離在3以內的記錄呢?下面在引入simhash的索引結構之前,先提供兩種常規的思路。第一種是方案是查詢待查詢文字的64位simhash code的所有3位以內變化的組合,大約需要四萬多次的查詢,參考下圖:
此處輸入圖片的描述
另一種方案是預生成庫中所有樣本simhash code的3位變化以內的組合,大約需要佔據4萬多倍的原始空間,參考下圖:
此處輸入圖片的描述
顯然,上述兩種方法,或者時間複雜度,或者空間複雜度,其一無法滿足實際的需求。我們需要一種方法,其時間複雜度優於前者,空間複雜度優於後者。

假設我們要尋找海明距離3以內的數值,根據抽屜原理,只要我們將整個64位的二進位制串劃分為4塊,無論如何,匹配的兩個simhash code之間至少有一塊區域是完全相同的,如下圖所示:
此處輸入圖片的描述
由於我們無法事先得知完全相同的是哪一塊區域,因此我們必須採用儲存多份table的方式。在本例的情況下,我們需要儲存4份table,並將64位的simhash code等分成4份;對於每一個輸入的code,我們通過精確匹配的方式,查詢前16位相同的記錄作為候選記錄,如下圖所示:
此處輸入圖片的描述讓我們來總結一下上述演算法的實質:
1、將64位的二進位制串等分成四塊
2、調整上述64位二進位制,將任意一塊作為前16位,總共有四種組合,生成四份table
3、採用精確匹配的方式查詢前16位
4、如果樣本庫中存有2^34(差不多10億)的雜湊指紋,則每個table返回2^(34-16)=262144個候選結果,大大減少了海明距離的計算成本

我們可以將這種方法拓展成多種配置,不過,請記住,table的數量與每個table返回的結果呈此消彼長的關係,也就是說,時間效率與空間效率不可兼得,參看下圖:
此處輸入圖片的描述
事實上,這就是Google每天所做的,用來識別獲取的網頁是否與它龐大的、數以十億計的網頁庫是否重複。另外,simhash還可以用於資訊聚類、檔案壓縮等。
由於文字已經壓縮成8個位元組了,因此其實Simhash近似查重精度並不高:
此處輸入圖片的描述

專案地址及經驗總結

相關推薦

Scrapy-redis增量以及Simhash相似

最近在實習,第一個任務就是從各大入口網站抓取新聞,爬蟲本身不是一個很難的事情,用scrapy框架很容易完成(關於scrapy的具體用法可以參考我之前的一篇部落格http://blog.csdn.net/john_xyz/article/details/78157

【實戰】scrapy-redis + webdriver 航空網站

引言 今天給大家帶來的是scrapy-redis + webdriver實戰案例。在爬蟲編寫過程中,我們經常會遇到以下的情況,想要用scrapy框架,但是因為網站的原因,還想要用webdriver,那麼要如何實現scrapy + webdriver呢?其實很簡單,大家都知道,在scrapy中,我

演算法:SimHash和MinHash

來源:http://grunt1223.iteye.com/blog/964564 在工作學習中,我往往感嘆數學奇蹟般的解決一些貌似不可能完成的任務,並且十分希望將這種喜悅分享給大家,就好比說:“老婆,出來看上帝”……  隨著資訊爆炸時代的來臨,網際網路上充斥著著大量的

[PHP] PHP多個進程配合redis的有序集合實現大

div with argv 多個 sets light mage alt 分享圖片 1.對一個大文件比如我的文件為 -rw-r--r-- 1 ubuntu ubuntu 9.1G Mar 1 17:53 2018-12-awk-uniq.txt 2.使用sp

redis實現scrapy的url增量

scrapy 自帶了去重方案,通過RFPDupeFilter類完成去重,檢視原始碼。 def request_seen(self, request): fp = self.request_fingerprint(request) if fp

Scrapy實現,使用Redis實現增量

一、使用場景: 定時爬取某網站的資料,每次爬取只爬取並儲存新增的資料到資料庫中,之前存過的資料不再入庫。 scrapy官方文件的去重模組,只能實現對當前抓取資料的去重,並不會和資料庫裡的資料做對比。當有一天需求變了,在你向mysql 資料庫儲存的時候,發現已經有一部分已經

scrapy利用redis實現url增量

引言之前資料採集時有2個需求就是url去重與資料的增量爬去(只能夠請求增加的url,不然會增加被爬網站的伺服器負荷),最開始的想法是指用redis的set實現url去重,但在後面開發中無意的解決了增量爬去的類容。下面貼上主要程式碼。具體實現步驟將每次爬去的連結存入redis(

Python網絡爬蟲Scrapy+MongoDB +Redis實戰騰訊視頻動態評論教學視頻

並發數 www. 深入 圖例 編程 ppt 研發 read 網絡爬蟲 課程簡介 學習Python爬蟲開發數據采集程序啦!網絡編程,數據采集、提取、存儲,陷阱處理……一站式全精通!!!目標人群掌握Python編程語言基礎,有誌從事網絡爬蟲開發及數據采集程序開發的人群。學習目

Scrapy實現對新浪微博某關鍵詞的以及不同url中重複內容的過濾

工作原因需要爬取微博上相關微博內容以及評論。直接scrapy上手,發現有部分重複的內容出現。(標題重複,內容重複,但是url不重複) 1.scrapy爬取微博內容  為了降低爬取難度,直接爬取微博的移動端:(電腦訪問到移動版本微博,之後F12調出控制檯來操作) 點選

scrapy框架下的豆瓣電影評論以及登入,以及生成詞雲和柱狀圖

由於豆瓣在今年5月份已經禁止展示所有短評,只展示最熱的500條資料,並且在爬取到240條的時候,如果沒有登入的話,會提示登入。 因此幾天的爬蟲,包括豆瓣的自動登入和資料爬取後批量存入pymysql資料庫。 在這個爬蟲完成後,其實我也在頁面上找了下,在全部評論

scrapy-deltafetch實現增量

前言 在之前的文章中我們都是對目標站點進行全量爬取,只要爬蟲run起來就會對所有的連結都爬取一遍,這其實是很傻的做法,因為很多情況下我們並不需要爬取已經爬過的連結,除非你需要定期更新這個連結對應頁面上的資料。好了,迴歸正題,本文介紹scrapy使用scrapy

scrapy結合selenium淘寶等動態網站

ice 網站 -i war 原因 def exe imp span 1.首先創建爬蟲項目 2.進入爬蟲 class TaobaoSpider(scrapy.Spider): name = ‘taobao‘ allowed_domains = [‘taobao.c

scrapy初探之武sir首頁博客

scrapy一、爬蟲 網絡爬蟲(又被稱為網頁蜘蛛,網絡機器人,在FOAF社區中間,更經常的稱為網頁追逐者),是一種按照一定的規則,自動地抓取萬維網信息的程序或者腳本。另外一些不常使用的名字還有螞蟻、自動索引、模擬程序或者蠕蟲。 二、scrapy框架 Scrapy是一個為了爬取網站數據,提取結構性數據而編寫的應

scrapy+selenium 淘寶商城商品數據存入到mongo中

mage 通過 -c style settings 一個 arc lec less 1.配置信息 # 設置mongo參數 MONGO_URI = ‘localhost‘ MONGO_DB = ‘taobao‘ # 設置搜索關鍵字 KEYWORDS=[‘小米手機‘,‘華為

小白scrapy爬蟲之簡書網頁並下載對應鏈接內容

tps python 分享 列表 scrapy 網頁 pytho 分享圖片 介紹 *準備工作: 爬取的網址:https://www.jianshu.com/p/7353375213ab 爬取的內容:下圖中python庫介紹的內容列表,並將其鏈接的文章內容寫進文本文件中 小

scrapy框架爬蟲糗事百科 之 Python爬蟲從入門到放棄第不知道多少天(1)

Scrapy框架安裝及使用 1. windows 10 下安裝 Scrapy 框架:   前提:安裝了python-pip    1. windows下按住win+R 輸入cmd   2. 在cmd 下 輸入       pip install scrapy       pip inst

scrapy-redis增量式爬蟲

1 在scrapy爬蟲的框架上setting.py中加上這四句 DUPEFILTER_CLASS = “scrapy_redis.dupefilter.RFPDupeFilter” #指定了排程器的類 SCHEDULER = “scrapy_redis.scheduler.Schedul

scrapy專案總結——汙染資料的專案

經過一段時間的學習,開始慢慢學會了使用scray簡單的爬取資料。 這個專案起源是對汙染資料的需求。 起初找到一個網站,嘗試對其進行爬取,但是網站涉及到動態載入的問題,目前本人只學會了靜態網站的爬取,所以放棄了。等後期學習後會返回進行嘗試。網址為: ht

scrapy根據關鍵字google圖片

瀏覽器的圖片都是通過Ajax非同步載入的,通過瀏覽器F12的network下的XHR可以看到,當往下拉動載入更多圖片時,XHR會加載出 許多內容,可以判定我們所需的資料可以通過這個介面拿到。下面是程式碼; spiders檔案 # -*- coding: utf-8 -*

python 爬蟲 如何通過scrapy框架簡單網站資訊--以51job為例

Scrapy框架三大優點: Scrapy框架是用純Python實現一個為了爬取網站資料、提取結構性資料而編寫的應用框架,用途非常廣泛。 框架的力量,使用者只需要定製開發幾個模組就可以輕鬆的實現一個爬蟲,用來抓取網頁內容以及各種圖片,非常之方便。 Scrapy