• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:phpでhtmlのタイトルを取得する方法について)

phpでURLからhtmlのタイトルを取得する方法と文字化け対策

このQ&Aのポイント
  • phpを使ってURLから指定されたサイトのタイトルを取得する方法について説明します。mb_internal_encoding関数を使用して文字コードを指定し、file_get_contents関数でHTMLを読み込みます。その後、mb_convert_encoding関数を使用してHTMLの文字コードをUTF-8に変換します。正規表現を使用してHTMLからタイトルを抽出し、取得します。しかし、一部のサイトで文字化けが発生する場合があります。文字化けしてしまったサイトの文字コードがx-sjisやEUC-JPの場合、取得したHTMLから文字コードを指定しているタグを抽出し、使用する文字コードを特定することができます。
  • php5.3.2のバージョンでは、mb_internal_encoding関数を使用して文字コードを設定することができます。また、file_get_contents関数を使用して指定したURLのHTMLを取得することもできます。mb_convert_encoding関数を使用してHTMLの文字コードをUTF-8に変換することができます。正規表現を使用してHTMLからタイトルを取得する方法も説明しました。文字化けしてしまったサイトの文字コードがx-sjisやEUC-JPの場合、文字コードを指定しているタグを抽出し、使用する文字コードを特定することもできます。
  • phpを使用してURLから指定されたサイトのタイトルを取得する方法について説明しました。mb_internal_encoding関数を使用して文字コードを指定し、file_get_contents関数でHTMLを読み込みます。mb_convert_encoding関数を使用してHTMLの文字コードをUTF-8に変換し、正規表現を使用してタイトルを抽出します。しかし、一部のサイトでは文字化けが発生する場合があります。文字化けしてしまったサイトの文字コードがx-sjisやEUC-JPの場合、文字コードを指定しているタグを取得し、使用する文字コードを特定することができます。

質問者が選んだベストアンサー

  • ベストアンサー
  • kobamotti
  • ベストアンサー率100% (3/3)
回答No.3

No.1で回答した者です。 とりあえず、期待通りの動作となったみたいでよかったです。 > mb_convert_encodingの第3引数でautoを指定する場合、 > 日本語を明示的に指定していないと変換に失敗する場合があるのでしょうか。 どうやらそうみたいですね、、、ネットで検索すると結構ヒットします。 私はいつも形式的に設定ファイルで mb_language("Japanese"); と指定していたので、この問題は知りませんでした。 > mb_convert_encoding関数の仕様では、 > autoを指定した場合、ASCII→JIS→UTF-8→EUC-JP→SJISの順で文字コードを自動検出するとなっており、 > Shift_JISで構成されたhtmlも正しく変換できるものと思っていたのですが.... 「日本語だよ」と明示しないとPHP(もしくはマルチバイト処理のエンジン)が他の文字コードと勘違いして変換してしまうのかもしれません(例えば、SJISなのに自動検出できず、EUC-JPと解釈して、EUC-JP→UTF-8の変換をしてしまう、といったふうに)。 >> 強いて言えば、"<" や ">" は正規表現上、意味のある文字ですのでエスケープが必要です。 念のためこれ調べなおしてみましたが、自信がなくなってきました。。 preg_quoteのマニュアルを見ると"<"や">"自体がメタ文字であるとされていますが、下記ページではエスケープされた状態をもってメタ文字としています。 http://jp.emeditor.com/help/howto/search/search_regexp_syntax.htm 私はpreg_quoteのマニュアルにしたがって、preg系の関数を使うときは"<"や">"もエスケープするようにしていましたが、これ、正規表現の種類(やエンジン)によって異なるものなのでしょうかね。 ちゃんと調べたいところですが、これがなかなかヒットしない。。。 エスケープしなかったがために期待しない結果になったという経験はないので、問題となるのはごくまれなケースなのかもしれませんが、いつかハマらないためにも確信は得ておきたいものです。 こういう場で回答しておきながら曖昧な情報ばかりで申し訳ありません。 色々と勉強のきっかけを与えてくださった質問者様に感謝です。 以上、長文失礼しました。

kzk_rocky
質問者

お礼

あの後、色々と試してみました。 私の必要とする情報は以下の方法で取得可能でしたので、参考までにソースをのせておきます。 mb_language("Japanese"); $html = file_get_contents($url); $code = 'SJIS, EUC-JP, UTF-8, ASCII, JIS'; $html = mb_convert_encoding($html, 'UTF-8', $code); if (eregi('<title>(.*)</title>', $html, $matches)) { $title = html_entity_decode(trim($matches[1]), ENT_NOQUOTES, "UTF-8"); }

その他の回答 (2)

回答No.2

こんにちは。 1.mb_detect_encodingを使って、$htmlの文字コードを検出する。 この場合、 $convertedHtml = mb_convert_encoding($html, 'UTF-8', '検出した文字コード'); となります。 2.正規表現で<meta content="text/html; charset=EUC-JP" http-equiv="Content-Type">を抜き取る。 書き方はいろいろあろうかと・・・。 preg_match('/<meta.*charset=([a-zA-Z_-]+)/i', $html, $matches); とか?

kzk_rocky
質問者

お礼

ご回答ありがとうございます。 1.の方法は試していませんが、 mb_detect_encodingの文字コード検出方法と、 mb_convert_encodingでautoを指定した場合の文字コード検出方法は違うのでしょうか。 2.の方法は参考にさせて頂きました。 一部修正を加えましたが、以下の正規表現で取得可能でした。 <meta.*charset=([a-zA-Z_0-9-]+) どうもありがとうございました。

  • kobamotti
  • ベストアンサー率100% (3/3)
回答No.1

もしかしてブラウザはInternet Explorerをお使いですか? 私はOpera使いですが、ご提示頂いたコードの結果を出力しても文字化けはしませんでした。 昔から個人的に抱いている印象ですが、IEはこの辺りの動作が不親切な気がします。 明示されていない仕様については我関せずという挙動なのか、 またはそもそもそこまで考えてすらいない(あるいは考えた上でスルーしている)のか、 よくわかりませんが(私は後者ではないかと予測しています)。 出力するコンテンツはhtmlということでよろしいですか? 以下のように出力htmlのheadタグ内で明示するか、 <html> <head> <meta http-equiv="Content-Type" content="application/xhtml+xml; charset=UTF-8" /> ・・・ </head> <body> ・・・ </body> </html> またはPHP側で下記のようなレスポンスヘッダを明示的に出力してみてください。 header("Content-Type:text/html; charset=UTF-8"); IEで確認してみましたが、私の環境ではこれでうまくいきました。 個人的には、今日のように数多くのブラウザが混在している昨今、 ブラウザ側の挙動のせいで頭を悩ませる/手を煩わせることなきよう、 上記のように出力エンコーディングは明示するべきだと思っています。 質問者様がご提示された正規表現にはそれほど致命的な問題はないと思っています。 強いて言えば、"<" や ">" は正規表現上、意味のある文字ですのでエスケープが必要です。 参考:http://php.net/manual/ja/function.preg-quote.php これでうまくいくといいのですが。 健闘を祈ります。

kzk_rocky
質問者

補足

ご回答ありがとうございます。 取得したタイトルは一旦DBにUTF-8で保存し、それをhtmlに出力します。 htmlの文字コードもUTF-8で、ヘッダにてcharset=UTF-8の指定もしております。 ちなみにIEでの確認はできていませんが、私の環境はGoogle ChromeとSafariです。 OSはMac OS 10.6を使用しております。 環境を明示しておらず、申し訳ございませんでした。 文字コードのことを指摘され、もしやと思い、 phpのソースでタイトルを取得する前に、mb_languageを使用して日本語を指定してみたところ、 文字化けせずにタイトルを取得できるようになりました。 mb_convert_encodingの第3引数でautoを指定する場合、 日本語を明示的に指定していないと変換に失敗する場合があるのでしょうか。 mb_convert_encoding関数の仕様では、 autoを指定した場合、ASCII→JIS→UTF-8→EUC-JP→SJISの順で文字コードを自動検出するとなっており、 Shift_JISで構成されたhtmlも正しく変換できるものと思っていたのですが.... > 強いて言えば、"<" や ">" は正規表現上、意味のある文字ですのでエスケープが必要です。 ご指摘ありがとうございます。 エスケープするようにします。