使用 Head-r 索引網頁
Head-r 是一個 免費 Perl 程式,它遞迴地跟蹤位於 (HTML) 網頁 頁面上的連結,這些頁面託管在 HTTP 伺服器上,並對使用者感興趣的連結執行 HEAD 請求。
該程式的預期用途是為以後選擇性地 映象 檔案託管站點建立 URI 列表。
head-r [-v|--verbose] [-j|--bzip2|-z|--gzip]
[--include-re=RE] [--exclude-re=RE]
[--depth=N] [--info-re=RE] [--descend-re=RE]
[-i|--input=FILE]... [-o|--output=FILE]
[-P|--no-proxy] [-U|--user-agent=USER-AGENT]
[-w|--wait=DELAY]
[--] [URI]...
可以說,最重要的 Head-r 選項是 --info-re= 和 --descend-re=,它們(透過 正則表示式)決定了哪些 URI 將被視為僅僅執行 HEAD 請求,以及 Head-r 將嘗試從哪些 URI 中獲取更多 URI。
對於以下示例,我們將使用 . - 匹配任何非空字串的正則表示式 - 允許 Head-r 對給定的兩個 URI 都執行 HEAD 請求。
$ head-r --info-re=. \
-- http://example.org/ http://example.net/
http://example.org/ 1381334900 1 1270 200
http://example.net/ 1381334903 1 1270 200
欄位以 ASCII HT(也稱為 TAB)程式碼分隔,並且如下所示
- URI;
- 時間戳(以自系統依賴紀元以來的秒數計;另見 Unix 時間);
- 在考慮此 URI 時使用的遞迴深度;
- 響應的長度(以位元組為單位)(根據
Content-Length:HTTP 回覆標頭); - HTTP 狀態程式碼 的回覆。
對於以下示例,我們還將透過使用 --descend-re=/\$ 選項來啟用實際的遞迴(仍然在最大深度為 1 時)。
$ head-r --info-re=. --descend-re=/\$ \
-- http://example.org/ http://example.net/
http://example.org/ 1381337824 1 1270 200
http://www.iana.org/domains/example 1381337829 0 200
http://example.net/ 1381337830 1 1270 200
如您所見,在 http://example.org/ 中,Head-r 找到了另一個要考慮的 URI:http://www.iana.org/domains/example,它對其進行了跟蹤併為此發出了 HEAD 請求。
很容易驗證 http://example.net/ 實際上也引用了相同的 URI。但是,由於 Head-r 記得它處理過的 URI(以及該點的遞迴深度),因此沒有發出其他請求。
現在考慮我們要遞迴遍歷的資源引用了我們不感興趣的 URI。對於以下示例,我們將使用比上面使用的 . 更具選擇性的正則表示式。
$ head-r --{info,descend}-re=wikipedia\\.org/wiki/ \
-- http://en.wikipedia.org/wiki/Main_Page
http://en.wikipedia.org/wiki/Main_Page 1381339589 1 61499 200
. . .
http://en.wikipedia.org/w/api.php?action=rsd
http://creativecommons.org/licenses/by-sa/3.0/
. . .
http://meta.wikimedia.org/
http://en.wikipedia.org/wiki/Wikipedia 1381339589 0 609859 200
http://en.wikipedia.org/wiki/Free_content 1381339589 0 124407 200
. . .
(請注意,我們只是使用了 Bash {,} 擴充套件 將相同的正則表示式傳遞給 --info-re= 和 --descend-re=。請確保調整到實際使用的 命令列直譯器。)
在上面的輸出中,一些 URI 沒有任何通常的資訊。這些 URI 是由 Head-r 找到的,但由於它們既不匹配“info”(--info-re=)也不匹配“descend”(--descend-re=)指定的正則表示式,因此沒有對它們執行任何操作。但是,這些 URI 仍然輸出,以防我們可能決定調整正則表示式本身。
--include-re= 和 --exclude-re= 正則表示式在所有其他正則表示式之前考慮,並且當前具有以下語義
- 包含正則表示式首先應用;如果 URI 與其中之一匹配,則將被考慮;
- 除非在上面的步驟中決定,否則將應用排除正則表示式;如果 URI 與其中之一匹配,則將不被考慮;
- 除非由上面的規則決定,否則 URI 將被考慮。
如果沒有給出這些選項,Head-r 將考慮任何 URI。
以下示例利用這些選項來進一步限制 Head-r 的輸出 對於上面的情況。
$ head-r --{include,descend}-re=wikipedia\\.org/wiki/ \
--{info,exclude}-re=. \
-- http://en.wikipedia.org/wiki/Main_Page
http://en.wikipedia.org/wiki/Main_Page 1381341336 1 61499 200
http://en.wikipedia.org/wiki/Wikipedia 1381341337 0 609859 200
http://en.wikipedia.org/wiki/Free_content 1381341337 0 124407 200
http://en.wikipedia.org/wiki/Encyclopedia 1381341337 0 151164 200
http://en.wikipedia.org/wiki/Wikipedia:Introduction 1381341337 0 50687 200
. . .
Head-r 能夠讀取它自己的輸出,因此為了避免發出重複的 HEAD 請求,以及為了發現要遞迴到其中的資源的 URI。
讓我們重新審視 我們之前的一個例子,我們現在將對其進行修改,使其只對幾個頁面發出 HEAD 請求
$ head-r --output=state.a \
--info-re='/(Free_content|Wikipedia)$' \
--descend-re=wikipedia\\.org/wiki/ \
-- http://en.wikipedia.org/wiki/Main_Page
$ grep -E \\s < state.a
http://en.wikipedia.org/wiki/Main_Page 1381417546 1 61499 200
http://en.wikipedia.org/wiki/Wikipedia 1381417546 0 609859 200
http://en.wikipedia.org/wiki/Free_content 1381417546 0 124407 200
$
現在,為什麼不包含更多頁面,比如所有以 F 開頭的名稱的頁面呢?
$ head-r \
--input=state.a --output=state.b \
--info-re=/wiki/F \
--descend-re=wikipedia\\.org/wiki/
$ grep -E \\s < state.b
http://en.wikipedia.org/wiki/File:Diary_of_a_Nobody_first.jpg 1381417906 0 34344 200
http://en.wikipedia.org/wiki/File:Progradungula_otwayensis_cropped.png 1381417906 0 30604 200
http://en.wikipedia.org/wiki/File:AW_TW_PS.jpg 1381417907 0 33297 200
http://en.wikipedia.org/wiki/Fran%C3%A7ois_Englert 1381417907 0 87860 200
http://en.wikipedia.org/wiki/File:Washington_Monument_Dusk_Jan_2006.jpg 1381417907 0 83137 200
http://en.wikipedia.org/wiki/File:Walt_Disney_Concert_Hall,_LA,_CA,_jjron_22.03.2012.jpg 1381417907 0 67225 200
http://en.wikipedia.org/wiki/Frank_Gehry 1381417907 0 152838 200
$
請注意,雖然我們的 --info-re= 明顯涵蓋了 http://en.wikipedia.org/wiki/Free_content,但沒有對該頁面發出 HEAD 請求,因為我們的 --input=state.a 檔案已經包含了相關資訊。
此外,由於我們要讓 Head-r 考慮的所有 URI 都已列在 state.a 中,因此沒有必要在命令列中指定任何 URI。當 URI 來自命令列引數和--input= 檔案時,來自命令列的 URI 將首先被考慮。
由於遞迴遍歷大型網站可能會導致大型輸出列表,因此 Head-r 提供對輸出資料的壓縮支援。
--bzip2 (-j) 和 --gzip (-z) 選項選擇用於輸出檔案(使用 --output= 指定或標準輸出)的壓縮方法。但是,如果啟用了壓縮並且輸出到 終端 裝置,Head-r 將退出並顯示錯誤。
Head-r 透明地解壓縮作為輸入給出的檔案 (--input=),這得益於 IO::Uncompress::AnyUncompress 庫。
有兩個選項會影響 Head-r 使用的 HTTP 客戶端的行為:--wait= (-w) 和 --user-agent= (-U)。
--wait= 選項指定兩次連續 HTTP 請求之間等待的時間(以秒為單位)。預設值為約 2.7 秒。
--user-agent= 選項指定在 HTTP 請求中使用的 User-Agent: 頭部的值,如果目標伺服器根據該頭部的值阻止訪問,這可能會有用。預設值由字串 HEAD-R-Bot/、Head-r 的版本以及使用的 libwww-perl 庫的標識組成。例如:HEAD-R-Bot/0.1 libwww-perl/6.05。
請考慮透過 CPAN RT 報告 Head-r 軟體中未列出的任何錯誤,https://rt.cpan.org/Public/Dist/Display.html?Name=head-r。本說明文件中的錯誤應報告到相應的 Wikibooks 討論頁面 - 或者您也可以自己修復它們!
對於任何其他自動檢索工具,濫用 Head-r 造成第三方伺服器過載並非不可能。建議使用者在使用該工具時,尤其是在降低 --wait= 設定和將最大遞迴 --depth= 提高到超出合理值的範圍時,考慮網路環境。
目前無法停用 /robots.txt 檔案處理。
程式碼只嘗試從標記為 text/html 媒體型別 的內容中檢索 URI,即使似乎可以相當容易地實現對 application/xhtml+xml(以及可能其他幾個 基於 XML 的型別,如 SVG)的支援。
首先將要檢索 URI 的資源載入到記憶體中,而應該可以動態地處理它。
從 --input= 檔案檢索到的遞迴深度的處理方式可能有些直觀,並且超出使用者的控制範圍。(儘管仍然可以使用第三方工具(如 AWK)編輯此類檔案。)
該程式碼為長期存在的 Net::HTTP 錯誤 #29468 實現了一個簡單的解決方法。
該程式碼的最新穩定版本可在 CPAN 獲取。例如,請檢視 https://metacpan.org/release/head-r 上的相應 Metacpan 頁面。
最新開發版本可以從 Git 儲存庫下載,例如
$ git clone -- \
http://am-1.org/~ivan/archives/git/head-r-2013.git/ head-r
Gitweb 介面可在 http://am-1.org/~ivan/archives/git/gitweb.cgi?p=head-r-2013.git 獲取。
Head-r 由 Ivan Shmakov 編寫。
Head-r 是自由軟體:您可以在自由軟體基金會發布的 GNU 通用公共許可證的條款下重新發布和/或修改它,無論是許可證的第 3 版,還是(根據您的選擇)任何更高版本。
本說明文件是在 Wikibooks 上進行的免費協作專案,根據 知識共享署名-相同方式共享許可證 (CC BY-SA) 3.0 版提供。