網絡爬蟲
網絡爬蟲(web crawler)可以在無需人類干預的狀況下自動進行一系列Web事務處理的軟件程序。不少爬蟲會從一個Web站點逛到另外一個Web站點,獲取內容,跟蹤超鏈,並對它們找到的數據進行處理。根據這些爬蟲自動探查Web站點的方式,網絡爬蟲也可稱做網絡蜘蛛、螞蟻、機器人等。
html
爬蟲及爬行方式
Web爬蟲會遞歸地對各類信息性Web站點進行遍歷,獲取第一個Web頁面,而後獲取那個頁面指向的全部Web頁面,而後是那些頁面指向的全部Web頁面,依此類推。遞歸地追蹤這些Web連接的爬蟲會沿着HTML超鏈建立的網絡"爬行",因此將其稱爲爬蟲(crawler)或蜘蛛(spider)。因特網搜索引擎使用爬蟲在Web上游蕩,並把它們碰到的文檔所有拉回來。而後對這些文檔進行處理,造成一個可搜索的數據庫,以便用戶查找包含了特定單詞的文檔。網上有數萬億的Web頁面須要查找和取回,這些搜索引擎必然是些最複雜的爬蟲。
web
從根集開始
在把飢餓的爬蟲放出去以前,須要給它一個起始點。爬蟲開始訪問的URL初始集合被稱做根集(root set)。挑選根集時,應該從足夠多不一樣的站點中選擇URL,這樣,爬遍全部的連接才能最終到達大部分你感興趣的Web頁面。根集中並不須要有不少頁面,就能夠涵蓋一大片Web結構,一般,一個好的根集會包括一些大的流行Web站點,好比,一個新建立頁面的列表和一個不常常被連接的無名頁面列表。不少大規模的爬蟲產品,好比因特網搜索引擎使用的那些爬蟲,都爲用戶提供了向根集中提交新頁面或無名頁面的方式。這個根集會隨時間推移而增加,是全部新爬蟲的種子列表。
算法
連接的提取以及相對連接的標準化
爬蟲在Web上移動時,會不停地對HTML頁面進行解析。它要對所解析的每一個頁面上的URL連接進行分析,並將這些連接添加到須要爬行的頁面列表中去。隨着爬蟲的前進,當其發現須要探查的新連接時,這個列表經常會迅速地擴張。爬蟲要經過簡單的HTML解析,將這些連接提取出來,並將相對URL轉換爲絕對形式。
數據庫
避免環路的出現
爬蟲在Web上爬行時,要特別當心不要陷入循環,或環路(cycle)之中。爬蟲必須知道它們到過何處,以免環路的出現。環路會形成爬蟲陷阱,這些陷阱會暫停或減緩爬蟲的爬行進程。
編程
循環與複製
至少出於下列三個緣由,環路對爬蟲來講是有害的:
數組
- 它們會使爬蟲陷入可能會將其困住的循環之中。循環會使未經良好設計的爬蟲不停地兜圈子,把全部時間都耗費在不停地獲取相同的頁面上。爬蟲會消耗掉不少網絡帶寬,可能徹底沒法獲取任何其餘頁面了。
- 爬蟲不斷地獲取相同的頁面時,另外一端的Web服務器也在遭受着打擊。若是爬蟲與服務器鏈接良好,它就會擊垮Web站點,阻止全部真實用戶訪問這個站點。這種拒絕服務是能夠做爲法律訴訟理由的。
- 即便循環自身不是什麼問題,爬蟲也是在獲取大量重複的頁面[一般被稱爲"dups"(重複),以便與"loops"(循環)押韻]。爬蟲應用程序會被重複的內容所充斥,這樣應用程序就會變得毫無用處。返回數百份徹底相同頁面的因特網搜索引擎就是一個這樣的例子。
記錄曾經到過哪些地方
記錄曾經到過哪些地方並不老是一件容易的事。因特網上有數十億個不一樣的Web頁面,其中還不包括那些由動態網關產生的內容。若是要爬行世界範圍內的一大塊Web內容,就要作好訪問數十億URL的準備。記錄下哪些URL已經訪問過了是件很具挑戰的事情。因爲URL的數量巨大,因此,要使用複雜的數據結構以便快速斷定哪些URL是曾經訪問過的。數據結構在訪問速度和內存使用方面都應該是很是高效的。數億URL須要具有快速搜索結構,因此速度是很重要的。窮舉搜索URL列表是根本不可能的。爬蟲至少要用到搜索樹或散列表,以快速斷定某個URL是否被訪問過。數億URL還會佔用大量的空間。
瀏覽器
大規模Web爬蟲對其訪問過的地址進行管理時使用的一些有用的技術:
緩存
- 樹和散列表:複雜的爬蟲可能會用搜索樹或散列表來記錄已訪問的URL。這些是加速URL查找的軟件數據結構。
- 有損的存在位圖:爲了減少空間,一些大型爬蟲會使用有損數據結構,好比存在位數組(presence bit array)。用一個散列函數將每一個URL都轉換成一個定長的數字,這個數字在數組中有個相關的"存在位"。爬行過一個URL時,就將相應的"存在位"置位。若是存在位已經置位了,爬蟲就認爲已經爬行過那個URL了。
- 檢查點:必定要將已訪問URL列表保存到硬盤上,以防爬蟲程序崩潰。
- 分佈式:隨着Web的擴展,在一臺計算機上經過單個爬蟲來完成爬行就變得不太現實了。那臺計算機可能沒有足夠的內存、磁盤空間、計算能力,或網絡帶寬來完成爬行任務。有些大型Web爬蟲會使用爬蟲"集羣",每一個獨立的計算機是一個爬蟲,以匯接方式工做。爲每一個爬蟲分配一個特定的URL"片",由其負責爬行。這些爬蟲配合工做,爬行整個Web。爬蟲個體之間可能須要相互通訊,來回傳送URL,以覆蓋出故障的對等實體的爬行範圍,或協調其工做。
別名與爬蟲環路
因爲URL"別名"的存在,即便使用了正確的數據結構,有時也很難分辨出之前是否訪問過某個頁面。若是兩個URL看起來不同,但實際指向的是同一資源,就稱這兩個URL互爲"別名"。
服務器
規範化URL
大多數Web爬蟲都試圖經過將URL"規範化"爲標準格式來消除上面那些顯而易見的別名。爬蟲首先可先將每一個URL都轉化爲規範化的格式,就能夠消除大部分別名問題了。但若是不知道特定Web服務器的相關信息,爬蟲就沒什麼好辦法來避免別名問題了。URL規範化能夠消除一些基本的語法別名,但爬蟲還會遇到其餘的、將URL轉換爲標準形式也沒法消除的URL別名。
網絡
經過下列步驟將每一個URL都轉化爲規範化的格式:
- 若是沒有指定端口的話,就向主機名中添加":80"。
- 將全部轉義符"%xx"都轉換成等價字符。
- 刪除"#"標籤。
特定Web服務器的相關信息:
- 爬蟲須要知道Web服務器是不是大小寫無關的才能避免別名問題。
- 爬蟲須要知道Web服務器上這個目錄下的索引頁面配置才能知道是不是別名。
- 即便爬蟲知道主機名和IP地址都指向同一臺計算機,它也還要知道Web服務器是否配置爲進行虛擬主機操做,才能知道這個URL是否是別名。
文件系統鏈接環路
文件系統中的符號鏈接會形成特定的潛在環路,由於它們會在目錄層次深度有限的狀況下,形成深度無限的假象。符號鏈接環路一般是由無意錯誤形成的,但也可能會惡意地爲爬蟲製造這樣的陷阱。
動態虛擬Web空間
可能會有意建立一些複雜的循環來陷害那些無辜的、毫無戒備的爬蟲。尤爲是,發佈一個看起來像普通文件,實際上倒是網關應用程序的URL是很容易的。這個應用程序能夠在傳輸中構造出包含了到同一服務器上虛構URL連接的HTML。請求這些虛構的URL時,服務器就會捏造出一個帶有新的虛構URL的新HTML頁面來。即便這個Web服務器實際上並不包含任何文件,它也能夠經過無限虛擬的Web空間將爬蟲帶入"夢境"。更糟的是,每次的URL和HTML看起來都有很大的不一樣,爬蟲很難檢測到環路。更常見的狀況是,可能會在無心中經過符號鏈接或動態內容構造出爬蟲陷阱。好比,一個基於CGI的日曆程序,它會生成一個月曆和一個指向下個月的連接。真正的用戶是不會不停地請求下個月的連接的,但不瞭解其內容的動態特性的爬蟲可能會不斷向這些資源發出無窮的請求。
避免循環和重複
沒有什麼簡單明瞭的方式能夠避免全部的環路。實際上,通過良好設計的爬蟲中要包含一組試探方式,以免環路的出現。總的說來,爬蟲的自動化程度越高(人爲的監管越少),越可能陷入麻煩之中。爬蟲的實現者須要作一些取捨——這些試探方式有助於避免問題的出現,但你可能會終止掃描那些看起來可疑的有效內容,所以這種方式也是"有損失"的。爬行Web這樣規模龐大的數據集時,好的爬蟲探測法老是會不斷改進其工做的。隨着新的資源類型不斷加入Web,它會隨着時間的推移構建出一些新的規則,並採納這些規則。好的規則老是在不斷髮展之中的。當受到錯誤爬蟲影響的資源(服務器、網絡帶寬等)處於可管理狀態,或者處於執行爬行工做的人的控制之下(好比在內部站點上)時,不少較小的、更具個性的爬蟲就會繞開這些問題。這些爬蟲更多的是依賴人類的監視來防止這些問題的 發生。
爬蟲會遇到的各類危險的Web中,有些技術的使用可使爬蟲有更好的表現:
- 規範化URL:將URL轉換爲標準形式以免語法上的別名。
- 廣度優先的爬行:每次爬蟲都有大量潛在的URL要去爬行。以廣度優先的方式來調度URL去訪問Web站點,就能夠將環路的影響最小化。即便碰到了爬蟲陷阱,也能夠在回到環路中獲取的下一個頁面以前,從其餘Web站點中獲取成百上千的頁面。若是採用深度優先方式,一頭扎到單個站點中去,就可能會跳入環路,永遠沒法訪問其餘站點。
- 節流:限制一段時間內爬蟲能夠從一個Web站點獲取的頁面數量。若是爬蟲跳進了一個環路,試圖不斷地訪問某個站點的別名,也能夠經過節流來限制重複的頁面總數和對服務器的訪問總數。
- 限制URL的大小:爬蟲可能會拒絕爬行超出特定長度(一般是1KB)的URL。若是環路使URL的長度增長,長度限制就會最終終止這個環路。有些Web服務器在使用長URL時會失敗,所以,被URL增加環路困住的爬蟲會使某些Web服務器崩潰。這會讓人錯誤地將爬蟲當成發起拒絕服務攻擊的攻擊者。要當心,這種技術確定會讓你錯過一些內容。如今不少站點都會用URL來管理用戶的狀態(好比,在一個頁面引用的URL中存儲用戶ID)。用URL長度來限制爬蟲可能會帶來些麻煩;但若是每當請求的URL達到某個特定長度時,都記錄一次錯誤的話,就能夠爲用戶提供一種檢查某特定站點上所發生狀況的方法。
- URL/站點黑名單:維護一個與爬蟲環路和陷阱相對應的已知站點及URL列表,而後像躲避瘟疫同樣避開它們。發現新問題時,就將其加入黑名單。這就要求有人工進行干預。但如今不少大型爬蟲產品都有某種形式的黑名單,用於避開某些存在固有問題或者有惡意的站點。還能夠用黑名單來避開那些對爬行大驚小怪的站點。
- 模式檢測:文件系統的符號鏈接和相似的錯誤配置所形成的環路會遵循某種模式;好比,URL會隨着組件的複製逐漸增長。有些爬蟲會將具備重複組件的URL看成潛在的環路,拒絕爬行帶有多於兩或三個重複組件的 URL。重複並不都是當即出現的。有些環路週期可能爲2或其餘間隔。有些爬蟲會查找具備幾種不一樣週期的重複模式。
- 內容指紋:一些更復雜的Web爬蟲會使用指紋這種更直接的方式來檢測重複。使用內容指紋的爬蟲會獲取頁面內容中的字節,並計算出一個校驗和(checksum)。這個校驗和是頁面內容的壓縮表示形式。若是爬蟲獲取了一個頁面,而此頁面的校驗和它曾經見過,它就不會再去爬行這個頁面的連接了——若是爬蟲之前見過頁面的內容,它就已經爬行過頁面上的連接了。必須對校驗和函數進行選擇,以求兩個不一樣頁面擁有相同校驗和的概率很是低。MD5這樣的報文摘要函數就常被用於指紋計算。有些Web服務器會在傳輸過程當中對頁面進行動態的修改,因此有時爬蟲會在校驗和的計算中忽略Web頁面內容中的某些部分,好比那些嵌入的連接。並且,不管定製了什麼頁面內容的動態服務器端包含(好比添加日期、訪問計數等)均可能會阻礙重複檢測。
- 人工監視:Web就是一片荒野。勇敢的爬蟲最終總會陷入一個採用任何技術都無能爲力的困境。設計全部產品級爬蟲時都要有診斷和日誌功能,這樣人類才能很方便地監視爬蟲的進展,若是發生了什麼不尋常的事情就能夠很快收到警告。在某些狀況下,憤怒的網民會給你發送一些無禮的郵件來提示你出了問題。
爬蟲的HTTP
爬蟲和全部其餘HTTP客戶端程序並無什麼區別。它們也要遵照HTTP規範中的規則。發出HTTP請求並將本身廣播成"HTTP/1.1"客戶端的爬蟲也要使用正確的HTTP請求首部。不少爬蟲都試圖只實現請求它們所查找內容所需的最小HTTP集。這會引起一些問題;但短時間內這種行爲不會發生什麼改變。結果就是,不少爬蟲發出的都是"HTTP/1.0"請求,由於這個協議的要求不多。
識別請求首部
儘管爬蟲傾向於只支持最小的HTTP集,但大部分爬蟲確實實現併發送了一些識別首部——最值得一提的就是User-Agent首部。建議爬蟲實現者們發送一些基本的首部信息,以通知各站點爬蟲的能力、爬蟲的標識符,以及它是從何處起源的。
在追蹤錯誤爬蟲的全部者,以及向服務器提供爬蟲所能處理的內容類型時,這些信息都是頗有用的。鼓勵爬蟲實現者們使用的基本識別首部包括以下內容:
- User-Agent:將發起請求的爬蟲名字告知服務器。
- From:提供爬蟲的用戶/管理員的E-mail地址。
- Accept:告知服務器能夠發送哪些媒體類型。這有助於確保爬蟲只接收它感興趣的內容(文本、圖片等)。
- Referer:提供包含了當前請求URL的文檔的URL。
虛擬主機
爬蟲實現者要支持Host首部。隨着虛擬主機的流行,請求中不包含Host首部的話,可能會使爬蟲將錯誤的內容與一個特定的URL關聯起來。所以,"HTTP/1.1"要求使用Host首部。在默認狀況下,大多數服務器都被配置爲提供一個特定的站點。所以,不包含Host首部的爬蟲向提供兩個站點的服務器發起請求時。
條件請求
儘可能減小爬蟲所要獲取內容的數量一般是頗有意義的。對因特網搜索引擎爬蟲來講,須要下載的潛在頁面有數十億,因此,只在內容發生變化時才從新獲取內容是頗有意義的。有些爬蟲實現了條件HTTP請求,它們會對時間戳或實體標籤進行比較,看看它們最近獲取的版本是否已經升級了。這與HTTP緩存查看已獲取資源的本地副本是否有效的方法很是類似。
對響應的處理
不少爬蟲的興趣主要在於用簡單的GET方法來獲取所請求的內容,因此,通常不會在處理響應的方式上花費太多時間。可是,使用了某些HTTP特性(好比條件請求)的爬蟲,以及那些想要更好地探索服務器,並與服務器進行交互的爬蟲則要可以對各類不一樣類型的HTTP響應進行處理。
- 狀態碼:爬蟲至少應該可以處理一些常見的,以及預期的狀態碼。全部爬蟲都應該理解"200 OK"和"404 Not Found"這樣的狀態碼。它們還應該可以根據響應的通常類別對它並不十分理解的狀態碼進行處理。
- 實體:除了HTTP首部所嵌的信息以外,爬蟲也會在實體中查找信息。HTML元標籤(好比元標籤http-equiv),就是內容編寫者用於嵌入資源附加信息的一種方式。服務器可能會爲它所處理的內容提供一些首部,標籤http-equiv爲內容編寫者提供了一種覆蓋這些首部的方式(meta http-equiv="Refresh" content="1;URL=index.html")。這個標籤會指示接收者處理這個文檔時,要看成其HTTP響應首部中有一個值爲"1, URL=index.html"的"Refresh HTTP"首部。有些服務器實際上會在發送HTML頁面以前先對其內容進行解析,並將http-equiv指令做爲首部包含進去;有些服務器則不會。爬蟲實現者可能會去掃描HTML文檔的HEAD組件,以查找http-equiv信息。
User-Agent導向
Web管理員應該記住,會有不少的爬蟲來訪問它們的站點,所以要作好接收爬蟲請求的準備。不少站點會爲不一樣的用戶代理進行內容優化,並嘗試着對瀏覽器類型進行檢測,以確保可以支持各類站點特性。這樣的話,當實際的HTTP客戶端根本不是瀏覽器,而是爬蟲的時候,站點爲爬蟲提供的就會是出錯頁面而不是頁面內容了。在某些搜索引擎上執行文本搜索,搜索短語"your browser does not support frames"(你的瀏覽器不支持框架),會生成一個包含那條短語的出錯頁面列表。站點管理員應該設計一個處理爬蟲請求的策略。好比,它們能夠爲全部其餘特性不太豐富的瀏覽器和爬蟲開發一些頁面,而不是將其內容限定在特定瀏覽器所支持的範圍。至少,管理員應該知道爬蟲是會訪問其站點的,不該該在爬蟲訪問時感到猝不及防。
行爲不當的爬蟲
不守規矩的爬蟲會形成不少嚴重問題:
- 失控爬蟲:爬蟲發起HTTP請求的速度要比在Web上衝浪的人類快得多,它們一般都運行在具備快速網絡鏈路的高速計算機上。若是爬蟲存在編程邏輯錯誤,或者陷入了環路之中,就可能會向Web服務器發出大量的負載——極可能會使服務器過載,並拒絕爲任何其餘人提供服務。全部的爬蟲編寫者都必須特別當心地設計一些保護措施,以免失控的爬蟲帶來的危害。
- 失效的 URL:有些爬蟲會去訪問URL列表。這些列表可能很老了。若是一個Web站點對其內容進行了大量的修改,爬蟲可能會對大量不存在的URL發起請求。這會激怒某些Web站點的管理員,他們不喜歡他們的錯誤日誌中充滿了對不存在文檔的訪問請求,也不但願提供出錯頁面的開銷下降其Web服務器的處理能力。
- 很長的錯誤 URL:因爲環路和編程錯誤的存在,爬蟲可能會向Web站點請求一些很大的、無心義的URL。若是URL足夠長的話,就會下降Web服務器的性能,使Web服務器的訪問日誌雜亂不堪,甚至會使一些比較脆弱的Web服務器崩潰。
- 愛打聽的爬蟲:有些爬蟲可能會獲得一些指向私有數據的URL,這樣,經過因特網搜索引擎和其餘應用程序就能夠很方便地訪問這些數據了。若是數據的全部者沒有主動宣傳這些Web頁面,那麼在最好的狀況下,他只是會認爲爬蟲的發佈行爲惹人討厭,而在最壞的狀況下,則會認爲這種行爲是對隱私的侵犯。一般,發生這種狀況是因爲爬蟲所跟蹤的、指向"私有"內容的超鏈已經存在了(也就是說,這些內容並不像其全部者認爲的那麼隱密,或者其全部者忘記刪除先前存在的超鏈了)。偶爾也會由於爬蟲很是熱衷於尋找某站點上的文檔而出現這種狀況,極可能就是在沒有顯式超鏈的狀況下去獲取某個目錄的內容形成的。從Web上獲取大量數據的爬蟲的實現者們應該清楚,他們的爬蟲極可能會在某些地方得到敏感的數據——站點的實現者不但願經過因特網可以訪問到這些數據。這些敏感數據可能包含密碼文件。很顯然,一旦被指出,就應該有某種機制能夠將這些數據丟棄(並從全部搜索索引或歸檔文件中將其刪除),這是很是重要的。如今已知一些惡意使用搜索引擎和歸檔的用戶會利用大型Web爬蟲來查找內容——有些搜索引擎, 實際上會對它們爬行過的頁面進行歸檔,這樣,即便內容被刪除了,在一段時間內仍是能夠找到並訪問它。
- 動態網關訪問:爬蟲並不老是知道它們訪問的是什麼內容。爬蟲可能會獲取一個內容來自網關應用程序的URL。在這種狀況下,獲取的數據可能會有特殊的目的,計算的開銷可能很高。不少Web站點管理員並不喜歡那些去請求網關文檔的幼稚爬蟲。
拒絕爬蟲訪問
爬蟲社團可以理解爬蟲訪問Web站點時可能引起的問題。1994 年,人們提出了一項簡單的自願約束技術,能夠將爬蟲阻擋在不適合它的地方以外,併爲網站管理員提供了一種可以更好地控制爬蟲行爲的機制。這個標準被稱爲"拒絕爬蟲訪問標準",但一般只是根據存儲訪問控制信息的文件而將其稱爲"robots.txt"。"robots.txt"的思想很簡單。全部Web服務器均可以在服務器的文檔根目錄中提供一個可選的、名爲"robots.txt"的文件。這個文件包含的信息說明了爬蟲能夠訪問服務器的哪些部分。若是爬蟲遵循這個自願約束標準,它會在訪問那個站點的全部其餘資源以前,從Web站點請求"robots.txt"文件。
拒絕爬蟲訪問標準
拒絕爬蟲訪問標準是一個臨時標準。不一樣的廠商實現了這個標準的不一樣子集。可是,具有一些對爬蟲訪問Web站點的管理能力,即便並不完美,也總比一點兒都沒有要好,並且大部分主要的生產廠商和搜索引擎爬蟲都支持這個拒絕訪問標準。如今大多數爬蟲採用的都是標準v0.0或v1.0。版本v2.0要複雜得多,沒有獲得普遍的應用。
Web站點和robots.txt文件
若是一個Web站點有"robots.txt"文件,那麼在訪問這個Web站點上的任意URL以前,爬蟲都必須獲取它並對其進行處理。由主機名和端口號定義的整個Web站點上僅有一個"robots.txt"資源。若是這個站點是虛擬主機,每一個虛擬的docroot均可以有一個不一樣的robots.txt文件,像全部其餘文件同樣。一般不能在Web站點上單獨的子目錄中安裝"本地robots.txt文件"。管理員要負責建立一個聚合型"robots.txt"文件,用以描述Web站點上全部內容的拒絕訪問規則。
- 獲取robots.txt:爬蟲會用HTTP的GET方法來獲取"robots.txt"資源,就像獲取Web服務器上全部其餘資源同樣。若是有"robots.txt"文件的話,服務器會將其放在一個"text/plain"主體中返回。若是服務器以"404 Not Found"HTTP狀態碼進行響應,爬蟲就能夠認爲這個服務器上沒有爬蟲訪問限制,它能夠請求任意的文件。爬蟲應該在From首部和User-Agent首部中傳輸標識信息,以幫助站點管理員對爬蟲的訪問進行跟蹤,並在站點管理員要查詢,或投訴的爬蟲事件中提供一些聯繫信息。
-
響應碼:不少Web站點都沒有"robots.txt"資源,但爬蟲並不知道這一點。它必須嘗試着從每一個站點上獲取"robots.txt"資源。爬蟲會根據對"robots.txt"檢索的結果採起不一樣的行動。
- 若是服務器以一個成功狀態(HTTP狀態碼2XX)爲響應,爬蟲就必須對內容進行解析,並使用排斥規則從那個站點上獲取內容。
- 若是服務器響應說明資源並不存在(HTTP狀態碼404),爬蟲就能夠認爲服務器沒有激活任何排斥規則,對此站點的訪問不受"robots.txt"的限制。
- 若是服務器響應說明有訪問限制(HTTP狀態碼401或403),爬蟲就應該認爲對此站點的訪問是徹底受限的。
- 若是請求嘗試的結果是臨時故障(HTTP狀態碼503),爬蟲就應該推遲對此站點的訪問,直到能夠獲取該資源爲止。
- 若是服務器響應說明是重定向(HTTP狀態碼3XX),爬蟲就應該跟着重定向,直到找到資源爲止。
robots.txt文件的格式
"robots.txt"文件採用了很是簡單的,面向行的語法。"robots.txt"文件中有三種類型的行:空行、註釋行和規則行。規則行看起來就像HTTP首部同樣,用於模式匹配。"robots.txt"文件中的行能夠從邏輯上劃分紅"記錄"。每條記錄都爲一組特定的爬蟲描述了一組排斥規則。經過這種方式,能夠爲不一樣的爬蟲使用不一樣的排斥規則。每條記錄中都包含了一組規則行,由一個空行或文件結束符終止。記錄以一個或多個User-Agent行開始,說明哪些爬蟲會受此記錄的影響,後面跟着一些Disallow和Allow行,用來講明這些爬蟲能夠訪問哪些URL。
此例顯示了一個"robots.txt"文件,這個文件容許爬蟲Slurp和Webcrawler訪問除了private子目錄下那些文件以外全部的文件。這個文件還會阻止全部其餘爬蟲訪問那個站點上的任何內容。
# this robots.txt file allows Slurp & Webcrawler to crawl # the public parts of our site, but no other robots... User-Agent: slurp User-Agent: webcrawler Disallow: /private User-Agent: * Disallow:
- User-Agent行:每一個爬蟲記錄都以一個或多個下列形式的User-Agent行開始。在爬蟲"HTTP GET"請求的User-Agent首部中發送(由爬蟲實現者選擇的)爬蟲名。若是爬蟲沒法找到與其名字相匹配的User-Agent行,並且也沒法找到通配的"User-Agent:*"行,就是沒有記錄與之匹配,訪問不受限。
爬蟲處理"robots.txt"文件時,它所遵循的記錄必須符合下列規則之一:
- 第一個robot-name是爬蟲名的大小寫無關的子字符串;
- 第一個robot-name爲「*」。
- Disallow和Allow行:Disallow和Allow行緊跟在爬蟲排斥記錄的User-Agent行以後。用來講明顯式禁止或顯式容許特定爬蟲使用哪些URL路徑。爬蟲那個必須將指望訪問的URL按序與排斥記錄中全部的Disallow和Allow規則進行匹配。使用找到的第一個匹配項。若是沒有找到匹配項,就說明容許使用這個URL。要使Allow/Disallow行與一個URL相匹配,規則路徑就必須是URL路徑大小寫相關的前綴。
- Disallow/Allow 前綴匹配:前綴匹配一般都能很好地工做,但有幾種狀況下它的表達力卻不夠強。若是但願不管使用什麼路徑前綴,都不容許爬行一些特別的子目錄,那"robots.txt"是無能爲力的。
Disallow/Allow前綴匹配的一些細節:
- Disallow和Allow規則要求大小寫相關的前綴匹配。(與User-Agent行不一樣)這裏的"*"(星號)沒什麼特殊的含義,但空字符串能夠起到通配符的效果。
- 在進行比較以前,要將規則路徑或URL路徑中全部"被轉義"的字符(%XX)都反轉爲字節(除了正斜槓%2F以外,它必須嚴格匹配)。
- 若是規則路徑爲空字符串,就與全部內容都匹配。
其餘有關robots.txt的知識
<p>解析 robots.txt 文件時還需遵循其餘一些規則。</p>
- 隨着規範的發展,"robots.txt"文件中可能會包含除了User-Agent、Disallow和Allow以外的其餘字段。爬蟲應該將全部它不理解的字段都忽略掉。
- 爲了實現後向兼容,不能在中間斷行。
- 註釋能夠出如今文件的任何地方;註釋包括可選的空格,以及後面的註釋符(#)、註釋符後面的註釋,直到行結束符爲止。
- 0.0版的拒絕爬蟲訪問標準並不支持Allow行。有些爬蟲只實現了0.0版的規範,所以會忽略Allow行。在這種狀況下,爬蟲的行爲會比較保守,有些容許訪問的URL它也不去獲取。
緩存和robots.txt的過時
若是一個爬蟲在每次訪問文件以前都要從新獲取"robots.txt"文件,Web服務器上的負載就會加倍,爬蟲的效率也會下降。爬蟲使用的替代方法是,它會週期性地獲取"robots.txt"文件,並將獲得的文件緩存起來。爬蟲會使用這個robots.txt文件的緩存副本,直到其過時爲止。原始服務器和爬蟲都會使用標準的HTTP存控制機制來控制"robots.txt"文件的緩存。爬蟲應該留意HTTP響應中的Cache-Control和Expires首部。如今不少產品級爬蟲都不是"HTTP/1.1"的客戶端;管理員應該意識到這些爬蟲不必定可以理解那些爲"robots.txt"資源提供的緩存指令。若是沒有提供Cache-Control指令,規範草案容許將其緩存7天。但實際上,這個時間一般太長了。不瞭解"robots.txt"文件的Web服務器管理員一般會在響應爬蟲的訪問時建立一個新的文件,但若是將缺少信息的"robots.txt"文件緩存一週,新建立的"robots.txt"文件就沒什麼效果了,站點管理員會責怪爬蟲管理員沒有遵照拒絕爬蟲訪問標準。
搜索引擎
獲得最普遍使用的Web爬蟲都是因特網搜索引擎。因特網搜索引擎能夠幫助用戶找到世界範圍內涉及任意主題的文檔。如今Web上不少最流行的站點都是搜索引擎。不少Web用戶將其做爲起始點,它們會爲用戶提供寶貴的服務,幫助用戶找到他們感興趣的信息。Web爬蟲爲因特網搜索引擎提供信息,它們獲取Web上的文檔,並容許搜索引擎建立索引,用以說明哪些文檔中有哪些詞存在。搜索引擎是Web爬蟲的主要來源。
大格局
Web發展的初期,搜索引擎就是一些至關簡單的數據庫,能夠幫助用戶在Web上定位文檔。如今,Web上有數十億可供訪問的頁面,搜索引擎已經成爲因特網用戶查找信息不可缺乏的工具。它們在不斷地發展,以應對Web龐大的規模,所以,如今已經變得至關複雜了。
面對數十億的Web頁面,和數百萬要查找信息的用戶,搜索引擎要用複雜的爬蟲來獲取這數十億Web頁面,還要使用複雜的查詢引擎來處理數百萬用戶產生的查詢負荷。產品級Web爬蟲的任務,要獲取搜索索引所需的頁面,它要發出數十億條HTTP請求。若是每條請求都要花半秒鐘的時間(對有些服務器來講可能慢了,對另外一些服務器來講可能快了)。若是請求是連續發出的,結果差很少是5700天!很顯然,大型爬蟲得更聰明一些,要對請求進行並行處理,並使用大量服務器來完成這項任務。但因爲其規模龐大,爬行整個Web仍然是件十分艱鉅的任務。
現代搜索引擎結構
如今的搜索引擎都構建了一些名爲"全文索引"的複雜本地數據庫,裝載了全世界的Web頁面,以及這些頁面所包含的內容。這些索引就像Web上全部文檔的卡片目錄同樣。搜索引擎爬蟲會蒐集Web頁面,把它們帶回家,並將其添加到全文索引中去。同時,搜索引擎用戶會經過HotBot或Google這樣的Web搜索網關對全文索引進行查詢。Web頁面老是在不斷地發生變化,並且爬行一大塊Web要花費很長的時間,因此全文索引充其量也就是Web的一個快照。
全文索引
全文索引就是一個數據庫,給它一個單詞,它能夠當即提供包含那個單詞的全部文檔。建立了索引以後,就不須要對文檔自身進行掃描了。
發佈查詢請求
用戶向Web搜索引擎網關發佈一條請求時,會填寫一個HTML表單,他的瀏覽器會用一個HTTP GET或POST請求將這個表單發送給網關。網關程序對搜索請求進行解析,並將Web UI查詢轉換成搜索全文索引所需的表達式。
對結果進行排序,並提供查詢結果
旦搜索引擎經過其索引獲得了查詢結果,網關應用程序會獲取結果,並將其拼成結果頁面提供給終端用戶。不少Web頁面均可能包含任意指定的單詞,因此搜索引擎採用了一些很聰明的算法,嘗試着對結果進行排名。爲了將相關度最高的結果提供給用戶,搜索引擎要知道應該按照什麼順序來提供結果列表中的文檔。這被稱爲相關性排名(relevancy ranking)——這是對一系列搜索結果的評分和排序處理。爲了更好地輔助這一進程,在爬行Web的過程當中都會進行數據統計。好比,對指向指定頁面的連接進行計數有助於判斷其流行程度,還能夠用此信息來衡量提供結果的順序。算法、爬行中獲取的輔助信息以及搜索引擎所使用的其餘技巧都是保守最森嚴的祕密。
欺詐
在搜索請求獲得的前幾個結果中沒有看到本身想要查找的內容時,用戶一般會感到很沮喪,所以,查找站點時搜索結果的順序是很重要的。在搜索管理員們認爲可以最好地描述其站點功能的單詞時,會有衆多因素激勵着這些管理員,努力使其站點排在靠近結果頂端的位置上,尤爲是那些依賴於用戶找到它們,並使用其服務的商業站點。這種對較好排列位置的期待引起了不少對搜索系統的博弈,也在搜索引擎的實現者和那些千方百計要將其站點列在突出位置的人之間引起了持久的拉鋸戰。不少管理員都列出了無數關鍵字(有些是絕不相關的),使用一些假冒頁面,或者採用欺詐行爲——甚至會用網關應用程序來生成一些在某些特定單詞上能夠更好地欺騙搜索引擎相關性算法的假冒頁面。這麼作的結果就是,搜索引擎和爬蟲實現者們要不斷地修改相關性算法,以便更有效地抓住這些欺詐者。