Command-Line

如何使用命令行獲取網站標題?

  • January 24, 2020

我想要一個列印網站標題的命令行程序。例如:

Alan:~ titlefetcher http://www.youtube.com/watch?v=Dd7dQh8u4Hc

應該給:

Why Are Bad Words Bad? 

你給它網址,它會列印出標題。

wget -qO- 'http://www.youtube.com/watch?v=Dd7dQh8u4Hc' |
 perl -l -0777 -ne 'print $1 if /<title.*?>\s*(.*?)\s*<\/title/si'

recode如果其中有類似的東西,您可以將其通過管道傳輸到 GNU <

wget -qO- 'http://www.youtube.com/watch?v=Dd7dQh8u4Hc' |
 perl -l -0777 -ne 'print $1 if /<title.*?>\s*(.*?)\s*<\/title/si' |
 recode html..

要移除 - youtube零件:

wget -qO- 'http://www.youtube.com/watch?v=Dd7dQh8u4Hc' |
perl -l -0777 -ne 'print $1 if /<title.*?>\s*(.*?)(?: - youtube)?\s*<\/title/si'

指出一些限制:

可移植性

沒有標準/攜帶式命令來執行 HTTP 查詢。幾十年前,我會推薦lynx -source這裡。但是現在,wget它更便攜,因為它可以在大多數 GNU 系統(包括大多數基於 Linux 的桌面/筆記型電腦作業系統)上預設找到。其他相當可移植的包括經常安裝的 libwwwGET附帶的命令,以及在較小程度上安裝的命令。其他常見的包括, , , …perl``lynx -source``curl``links -source``elinks -source``w3m -dump_source``lftp -c cat

HTTP 協議和重定向處理

wget``firefox可能不會獲得與例如將顯示的頁面相同的頁面。原因是 HTTP 伺服器可能會根據客戶端發送的請求中提供的資訊選擇發送不同的頁面。

wget/w3m/GET… 發送的請求將不同於 firefox 發送的請求。如果這是一個問題,您可以wget通過選項更改行為以更改它發送請求的方式。

在這方面最重要的是:

  • AcceptAccept-language: 告訴伺服器客戶端希望以哪種語言和字元集獲得響應。wget預設情況下不發送任何內容,因此伺服器通常會使用其預設設置發送。firefox另一端可能配置為請求您的語言。
  • User-Agent: 向伺服器標識客戶端應用程序。有些網站會根據客戶端發送不同的內容(儘管這主要是因為 javascript 語言解釋之間的差異),如果您使用的是機器人類型的使用者代理,例如wget.
  • Cookie:如果您以前訪問過該網站,您的瀏覽器可能會為其設置永久 cookie。wget將不會。

wget當它們在 HTTP 協議級別完成時將遵循重定向,但由於它不查看頁面的內容,而不是由 javascript 或<meta http-equiv="refresh" content="0; url=http://example.com/">.

性能/效率

在這裡,出於懶惰,我們perl在開始尋找<title>標籤之前已經閱讀了記憶體中的全部內容。鑑於標題位於<head>文件前幾個字節的部分中,這不是最佳選擇。如果 GNUawk在您的系統上可用,更好的方法可能是:

wget -qO- 'http://www.youtube.com/watch?v=Dd7dQh8u4Hc' |
 gawk -v IGNORECASE=1 -v RS='</title' 'RT{gsub(/.*<title[^>]*>/,"");print;exit}'

這樣, awk 在第一個 之後停止讀取</title,並通過退出導致wget停止下載。

解析 HTML

在這裡,wget在下載頁面時寫入頁面。同時,perl, 將其輸出 ( ) 整體儲存在記憶體中,然後列印在和-0777 -n的第一次出現之間找到的 HTML 程式碼。<title...>``</title

這適用於大多數具有<title>標籤的 HTML 頁面,但在某些情況下它不起作用。

相比之下,coffeeMug ​​的解決方案會將 HTML 頁面解析為 XML 並返回title. 如果保證頁面是有效的 XML則更正確。然而,HTML 不需要是有效的 XML(舊版本的語言不是),而且因為大多數瀏覽器都很寬鬆並且會接受不正確的 HTML 程式碼,所以甚至有很多不正確的 HTML 程式碼。

我的解決方案和咖啡杯的解決方案都會因各種極端情況而失敗,有時相同,有時則不然。

例如,我的將失敗:

<html><head foo="<title>"><title>blah</title></head></html>

或者:

<!-- <title>old</title> --><title>new</title>

雖然他將失敗:

<TITLE>foo</TITLE>

(有效的 html,而不是 xml)或:

或者:

<title>...</title>
...
<script>a='<title>'; b='</title>';</script>

(同樣,有效html的,缺少<![CDATA[的部分使其成為有效的 XML)。

<title>foo <<<bar>>> baz</title>

(不正確的 html,但仍然存在並被大多數瀏覽器支持)

解釋標籤內的程式碼。

<title>該解決方案在和之間輸出原始文本</title>。通常,其中不應該有任何 HTML 標記,可能會有註釋(儘管某些瀏覽器(如 firefox)不處理,所以不太可能)。可能還有一些 HTML 編碼:

$ wget -qO- 'http://www.youtube.com/watch?v=CJDhmlMQT60' |
 perl -l -0777 -ne 'print $1 if /<title.*?>\s*(.*?)\s*<\/title/si'
Wallace & Gromit - The Cheesesnatcher Part 1 (claymation) - YouTube

由 GNU 處理recode

$ wget -qO- 'http://www.youtube.com/watch?v=CJDhmlMQT60' |
 perl -l -0777 -ne 'print $1 if /<title.*?>\s*(.*?)\s*<\/title/si' |
  recode html..
Wallace & Gromit - The Cheesesnatcher Part 1 (claymation) - YouTube

但是,Web 客戶端還意味著在顯示標題時對該程式碼進行更多轉換(例如壓縮一些空白,刪除前導和尾隨的)。但是,不太可能需要這樣做。因此,與其他情況一樣,由您決定是否值得付出努力。

字元集

在 UTF-8 之前,iso8859-1 曾經是網路上用於非 ASCII 字元的首選字元集,儘管嚴格來說它們必須寫為é. HTTP 和 HTML 語言的最新版本增加了在 HTTP 標頭或 HTML 標頭中指定字元集的可能性,並且客戶端可以指定它接受的字元集。如今,UTF-8 往往是預設字元集。

所以,這意味著在那裡,你會發現é寫成é, as é, as UTF-8 é, (0xc3 0xa9), as iso-8859-1 (0xe9), 最後兩個,有時是關於字元集的資訊在 HTTP 標頭或 HTML 標頭(不同格式)中,有時不是。

wget只獲取原始字節,它不關心它們作為字元的含義,也不告訴 Web 伺服器首選的字元集。

recode html..將注意將éoré轉換為系統上使用的字元集的正確字節序列,但對於其餘的,這更棘手。

如果您的系統字元集是 utf-8,那麼在大多數情況下它都會沒問題,因為這往往是現在使用的預設字元集。

$ wget -qO- 'http://www.youtube.com/watch?v=if82MGPJEEQ' |
perl -l -0777 -ne 'print $1 if /<title.*?>\s*(.*?)\s*<\/title/si'
Noir Désir - L'appartement - YouTube

上面é是一個 UTF-8 é

但是,如果您想覆蓋其他字元集,則必須再次處理它。

還應注意,此解決方案根本不適用於 UTF-16 或 UTF-32 編碼的頁面。

總結一下

理想情況下,您需要的是一個真正的網路瀏覽器來為您提供資訊。也就是說,您需要使用適當的參數來執行 HTTP 請求,正確解釋 HTTP 響應,像瀏覽器一樣完全解釋 HTML 程式碼,並返回標題。

因為我不認為這可以在我知道的瀏覽器的命令行上完成(雖然現在看到這個技巧lynx),你必須求助於啟發式和近似,上面的一個和任何一個一樣好。

您可能還需要考慮性能、安全性…例如,要涵蓋所有情況(例如,從 3rd 方站點提取一些 javascript 的網頁,該站點設置標題或重定向到另一個頁面onload 鉤子),您可能必須使用其 dom 和 javascript 引擎實現現實生活中的瀏覽器,這些引擎可能必須對單個 HTML 頁面進行數百次查詢,其中一些試圖利用漏洞……

雖然使用正則表達式來解析 HTML 經常不受歡迎,但這是一個典型的案例,它足以勝任這項任務 (IMO)。

引用自:https://unix.stackexchange.com/questions/103252