Webサイトのタイトルを出力するコマンドラインプログラムが必要です。例:
Alan:~ titlefetcher http://www.youtube.com/watch?v=Dd7dQh8u4Hc
与える必要があります:
Why Are Bad Words Bad?
URLを指定すると、タイトルが出力されます。
wget -qO- 'http://www.youtube.com/watch?v=Dd7dQh8u4Hc' |
Perl -l -0777 -ne 'print $1 if /<title.*?>\s*(.*?)\s*<\/title/si'
<
のようなものがそこにある場合は、GNU recode
にパイプすることができます。
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
を勧めたでしょう。しかし、最近では、ほとんどのGNU=ほとんどのLinuxベースのデスクトップ/ラップトップオペレーティングシステムを含む)システムでデフォルトで検出できるため、wget
はよりポータブルです。他のかなりポータブルなものには、付属のGET
コマンドが含まれます頻繁にインストールされるPerl
のlibwww、lynx -source
、およびより少ない程度curl
を使用します。その他common ones include links -source
、elinks -source
、w3m -dump_source
、 lftp -c cat
...
wget
は、たとえばfirefox
が表示するページと同じページを取得しない場合があります。その理由は、HTTPサーバーが、クライアントから送信されたリクエストで提供された情報に基づいて、別のページを送信することを選択する可能性があるためです。
Wget/w3m/GET ...によって送信される要求は、firefoxによって送信される要求とは異なります。それが問題である場合は、wget
の動作を変更して、オプションを使用してリクエストを送信する方法を変更できます。
この点でここで最も重要なものは次のとおりです。
Accept
およびAccept-language
:クライアントが応答を取得する言語と文字セットをサーバーに通知します。wget
はデフォルトでは何も送信しないため、サーバーは通常、デフォルトの設定で送信します。反対側のfirefox
は、おそらく言語を要求するように構成されています。User-Agent
:サーバーに対してクライアントアプリケーションを識別します。一部のサイトは、クライアントに基づいて異なるコンテンツを送信しますが(これは主にJavaScript言語の解釈の違いのためです)、wget
のようなrobot-typeユーザーエージェントを使用している場合、サービスの提供を拒否することがあります。Cookie
:以前にこのサイトにアクセスしたことがある場合、ブラウザに永続的なCookieが設定されている可能性があります。 wget
はしません。wget
は、HTTPプロトコルレベルでリダイレクトが行われるときにリダイレクトに従いますが、ページのコンテンツではなく、JavaScriptや<meta http-equiv="refresh" content="0; url=http://example.com/">
などで行われるリダイレクトではありません。
ここでは、怠惰であるため、<title>
タグの検索を開始する前に、メモリ内のコンテンツ全体をPerl
読み取ります。タイトルがファイルの最初の数バイトにある<head>
セクションにあるとすると、それは最適ではありません。 GNU awk
がシステムで使用可能な場合、より良いアプローチは次のとおりです。
wget -qO- 'http://www.youtube.com/watch?v=Dd7dQh8u4Hc' |
gawk -v IGNORECASE=1 -v RS='</title' 'RT{gsub(/.*<title[^>]*>/,"");print;exit}'
このように、awkは最初の</title
の後に読み取りを停止し、終了することでwget
がダウンロードを停止するようにします。
ここで、wget
はダウンロード時にページを書き込みます。同時に、Perl
は出力(-0777 -n
)全体をメモリ内で丸呑みし、最初に出現する<title...>
と</title
の間にあるHTMLコードを出力します。
これは、<title>
タグが付いているほとんどのHTMLページで機能しますが、機能しない場合もあります。
対照的に、 coffeeMugのソリューション は、HTMLページをXMLとして解析し、title
の対応する値を返します。より正確ですページが有効なXMLであることが保証されている場合。ただし、HTMLは有効なXMLである必要はありません(以前のバージョンの言語はそうではありませんでした)。ほとんどのブラウザーは寛大であり、正しくないHTMLコードを受け入れるため、そこには多くの誤ったHTMLコードさえあります。
私のソリューションと coffeeMug's は、さまざまなコーナーケースで失敗します。
たとえば、私は失敗します:
<html><head foo="<title>"><title>blah</title></head></html>
または:
<!-- <title>old</title> --><title>new</title>
彼が失敗する間:
<TITLE>foo</TITLE>
(xmlではなく有効なhtml)または:
または:
<title>...</title>
...
<script>a='<title>'; b='</title>';</script>
(ここでも、有効なhtml
、有効なXMLにするための<![CDATA[
パーツがありません)。
<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文字のWebではpreferred文字セットでした。最近のバージョンのHTTPおよびHTML言語では、HTTPヘッダーまたはHTMLヘッダーで文字セットを指定できるようになり、クライアントは受け入れる文字セットを指定できます。現在、UTF-8がデフォルトの文字セットになる傾向があります。
つまり、これはé
がé
として、é
として、UTF-8として記述されていることを意味しますé
、(0xc3 0xa9)、iso- 8859-1(0xe9)、最後の2つについては、HTTPヘッダーまたはHTMLヘッダー(異なる形式)の文字セットに関する情報が含まれる場合とそうでない場合があります。
wget
は、生のバイトのみを取得します。文字としての意味を考慮せず、優先する文字セットをWebサーバーに通知しません。
recode html..
は、é
またはé
を、システムで使用されている文字セットの適切なバイトシーケンスに変換するように注意しますが、それ以外の場合は、より注意が必要です。
システムの文字セットが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でエンコードされたページではまったく機能しないことにも注意してください。
理想的には、ここで必要なのは、情報を提供する実際のWebブラウザーです。つまり、適切なパラメーターを使用してHTTP要求を実行し、HTTP応答を正しく解釈し、ブラウザーが行うようにHTMLコードを完全に解釈し、タイトルを返すために何かが必要です。
私が知っているブラウザーを使用してコマンドラインで実行できるとは思わないので(今すぐ lynx
でこのトリックを参照してください)、ヒューリスティックと近似に頼る必要があります。上記のものはどれも同じです。
また、パフォーマンス、セキュリティを考慮したい場合もあります。たとえば、すべてのケース(たとえば、タイトルを設定したり、別のページにリダイレクトしたりするサードパーティのサイトからJavaScriptを取得したWebページ) onloadフック)、単一のHTMLページに対して何百ものクエリを実行する必要があるdomおよびJavaScriptエンジンを備えた実際のブラウザを実装する必要がある場合があります。その一部は脆弱性を悪用しようとします...
正規表現を使用してHTMLを解析することはよくありませんが 、ここでは、タスク(IMO)に十分に対応できる典型的なケースを示します。
次のように、hxselect
をwget
で( HTML-XML-Utils から)試すこともできます。
_wget -qO- 'http://www.youtube.com/watch?v=Dd7dQh8u4Hc' | hxselect -s '\n' -c 'title' 2>/dev/null
_
以下を使用して、Debianベースのディストリビューションにhxselect
をインストールできます。
_Sudo apt-get install html-xml-utils
_。
STDERRリダイレクトは、Input is not well-formed. (Maybe try normalize?)
メッセージを回避することです。
「-YouTube」を取り除くには、上記のコマンドの出力をawk '{print substr($0, 0, length($0)-10)}'
にパイプします。
curl
およびgrep
を使用してこれを行うこともできます。 grep
で PCRE(Perl互換の正規表現) を使用することで、<title>...</title>
タグを見つけることができるように、機能を後回しにして先読み機能を利用できるようにする必要があります。
$ curl 'http://www.youtube.com/watch?v=Dd7dQh8u4Hc' -so - | \
grep -iPo '(?<=<title>)(.*)(?=</title>)'
Why Are Bad Words Bad? - YouTube
curl
スイッチ:
-s
=サイレント-o -
=出力をSTDOUTに送信しますgrep
スイッチ:
-i
=大文字と小文字を区別しない-o
=一致する部分のみを返します-P
= PCREモードgrep
のパターン:
(?<=<title>)
=これの左側にある、これで始まる文字列を探します(?=</title>)
=これの右側にある、これで終わる文字列を探します(.*)
= <title>..</title>
の間のすべて。<title>...</titie>
が複数行にわたる場合、上記では見つかりません。 tr
を使用して\n
文字、つまりtr -d '\n'
を削除すると、この状況を緩和できます。
サンプルファイル。
$ cat multi-line.html
<html>
<title>
this is a \n title
</TITLE>
<body>
<p>this is a \n title</p>
</body>
</html>
そしてサンプル実行:
$ curl 'http://www.jake8us.org/~sam/multi-line.html' -so - | \
tr -d '\n' | \
grep -iPo '(?<=<title>)(.*)(?=</title>)'
this is a \n title
<title>
が<title lang="en">
のように設定されている場合は、grep
ingする前にこれを削除する必要があります。これを行うには、ツールsed
を使用できます。
$ curl 'http://www.jake8us.org/~sam/multi-line.html' -so - | \
tr -d '\n' | \
sed 's/ lang="\w+"//gi' | \
grep -iPo '(?<=<title>)(.*)(?=</title>)'
this is a \n title
上記は、大文字と小文字を区別しない文字列lang=
に続いてWordシーケンス(\w+
)を検出します。その後、取り除かれます。
ある時点で、正規表現はこのタイプの問題の解決に失敗します。その場合は、実際のHTML/XMLパーサーを使用することをお勧めします。そのようなパーサーの1つは Nokogiri です。 RubyはGemとして利用でき、次のように使用できます:
$ curl 'http://www.jake8us.org/~sam/multi-line.html' -so - | \
Ruby -rnokogiri -e \
'puts Nokogiri::HTML(readlines.join).xpath("//title").map { |e| e.content }'
this is a \n title
上記は、curl
を介して取得したデータをHTML(Nokogiri::HTML
)として解析しています。次に、xpath
メソッドは、title
という名前のリーフノード(//
)であるHTML内のノード(タグ)を検索します。見つかったそれぞれについて、そのコンテンツ(e.content
)を返します。次にputs
はそれらを出力します。
Perlと HTML :: TreeBuilder :: XPath モジュールでも同様のことができます。
$ cat title_getter.pl
#!/usr/bin/Perl
use HTML::TreeBuilder::XPath;
$tree = HTML::TreeBuilder::XPath->new_from_url($ARGV[0]);
($title = $tree->findvalue('//title')) =~ s/^\s+//;
print $title . "\n";
次に、このスクリプトを次のように実行できます。
$ ./title_getter.pl http://www.jake8us.org/~sam/multi-line.html
this is a \n title
単純な正規表現を使用してHTMLを解析するのは簡単です。例えば。改行を含み、ファイルで指定された特殊文字エンコーディングを無視します。正しいことを行い、他の回答で言及されている他の実際のパーサーのいずれかを使用してページを実際に解析するか、次の1つのライナーを使用します。
python -c "import bs4, urllib2; print bs4.BeautifulSoup(urllib2.urlopen('http://www.crummy.com/software/BeautifulSoup/bs4/doc/')).title.text"
(上記にはUnicode文字が含まれています)。
BeautifulSoupは、多くの誤ったHTML(たとえば、終了タグが欠落している)も処理します。これにより、単純化された正規表現が完全にスローされます。標準のpythonを使用してインストールできます。
pip install beautifulsoup4
または、pip
がない場合は、
easy_install beautifulsoup4
Debian/Ubuntuなどの一部のオペレーティングシステムでもパッケージ化されています(python-bs4
Debian/Ubuntuのパッケージ)。
多分それは「不正行為」ですが、1つのオプションは pup、コマンドラインHTMLパーサー です。
これを行うには2つの方法があります。
meta
フィールドとproperty="og:title
属性の使用
$ wget -q 'http://www.youtube.com/watch?v=Dd7dQh8u4Hc' -O - | \
> pup 'meta[property=og:title] attr{content}'
Why Are Bad Words Bad?
title
フィールドを直接使用する別の方法(そして最後に- YouTube
文字列を削除する)。
$ wget -q 'http://www.youtube.com/watch?v=Dd7dQh8u4Hc' -O - | \
> pup 'title text{}' | sed 's/ - YouTube$//'
Why Are Bad Words Bad?
このトリックを使用すると、lynx
で可能であるようです:
lynx 3>&1 > /dev/null -nopause -noprint -accept_all_cookies \
-cmd_script /dev/stdin<<'EOF' 'http://www.youtube.com/watch?v=Dd7dQh8u4Hc'
set PRINTER=P:printf '%0s\\n' "$LYNX_PRINT_TITLE">&3:TRUE
key p
key Select key
key ^J
exit
EOF
これは実際のWebブラウザーなので、筆者が other answer で言及した制限の多くに悩まされることはありません。
ここでは、ページを印刷するときに、lynx
が$LYNX_PRINT_TITLE
環境変数を現在のページのタイトルに設定するという事実を使用しています。
上記では、lynx
スクリプト機能を使用して(ヒアドキュメント経由で標準入力に渡されるスクリプトを使用)、次のことを行います。
3
に出力するP
と呼ばれるlynx "プリンター"を定義します(そのファイル記述子はlynx
のstdoutに3>&1
でリダイレクトされます。 lynx stdout自体は/ dev/nullにリダイレクトされます)。^J
)。簡単な方法:
curl -s example.com | grep -o "<title>[^<]*" | tail -c+8
いくつかの選択肢:
curl -s example.com | grep -o "<title>[^<]*" | cut -d'>' -f2-
wget -qO- example.com | grep -o "<title>[^<]*" | sed -e 's/<[^>]*>//g'
LynxとLYNX_PRINT_TITLEを使用するStéphaneChazelasのアイデアは気に入りましたが、Ubuntu 14.04.5ではそのスクリプトは機能しませんでした。
Lynxを実行し、事前に構成されたファイルを使用して、簡易バージョンを作成しました。
/etc/lynx-cur/lynx.cfg(またはlynx.cfgがある場所)に次の行を追加します。
PRINTER:P:printenv LYNX_PRINT_TITLE>/home/account/title.txt:TRUE:1000
この行は、印刷中にタイトルを「/home/account/title.txt」に保存するように指示します。任意のファイル名を選択できます。非常に大きなページを要求し、上記の値を「1000」から1ページあたりの任意の行数に増やします。それ以外の場合、Lynxは「非常に多数のページを含むドキュメントを印刷するときに」追加のプロンプトを表示します。
次に、次の内容で/home/account/lynx-script.txtファイルを作成します。
key p
key Select key
key ^J
exit
次に、次のコマンドラインオプションを使用してLynxを実行します。
lynx -term=vt100 -display_charset=utf-8 -nopause -noprint -accept_all_cookies -cmd_script=/home/account/lynx-script.txt "http://www.youtube.com/watch?v=Dd7dQh8u4Hc" >/dev/nul
このコマンドが完了すると、ファイルの/home/account/title.txtがページのタイトルとともに作成されます。
簡単に言えば、ここにPHP関数が、指定されたURLに基づいてページタイトルを返すか、エラーの場合はfalseを返します。
function GetUrlTitle($url)
{
$title_file_name = "/home/account/title.txt";
if (file_exists($title_file_name)) unlink($title_file_name); // delete the file if exists
$cmd = '/usr/bin/lynx -cfg=/etc/lynx-cur/lynx.cfg -term=vt100 -display_charset=utf-8 -nopause -noprint -accept_all_cookies -cmd_script=/home/account/lynx-script.txt "'.$url.'"';
exec($cmd, $output, $retval);
if (file_exists($title_file_name))
{
$title = file_get_contents($title_file_name);
unlink($title_file_name); // delete the file after reading
return $title;
} else
{
return false;
}
}
print GetUrlTitle("http://www.youtube.com/watch?v=Dd7dQh8u4Hc");
Nokogiriを使用すると、簡単なCSSベースのクエリを使用してタグの内部テキストを抽出できます。
$ nokogiri -e 'puts $_.at_css("title").content'
Why Are Bad Words Bad? - YouTube
同様に、タグの「content」属性の値を抽出するには:
$ nokogiri -e 'puts $_.at_css("meta[name=title]").attr("content")'
Why Are Bad Words Bad?
Python3 + beautifulsoupの例は
python3 -c "import bs4, requests; print(bs4.BeautifulSoup(requests.get('http://www.crummy.com/software/BeautifulSoup/bs4/doc/').content).title.text)"
Xidelを使用する:
$ xidel -s http://www.youtube.com/watch?v=Dd7dQh8u4Hc --css title
Why Are Bad Words Bad? - YouTube
必要であれば、 apt install xidel
または類似。