サンプル・プログラムの実行例
サンプル・プログラム
DOMscraping.php | サンプル・プログラム本体。 |
pahooScraping.php | RSS処理に関わるクラス pahooScraping。 スクレイピング処理に関わるクラスの使い方は「PHPで作るRSSビューア」を参照。include_path が通ったディレクトリに配置すること。 |
pahooInputData.php | データ入力に関わる関数群。 使い方は「数値入力とバリデーション」「文字入力とバリデーション」などを参照。include_path が通ったディレクトリに配置すること。 |
バージョン | 更新日 | 内容 |
---|---|---|
4.0.1 | 2023/09/29 | bug-fix |
2.0.0 | 2023/09/18 | pahooScrapingクラスに変更 |
1.1 | 2021/05/08 | PHP8対応,リファラ・チェック改良 |
1.0 | 2015/10/20 |
関数/メソッド | 機能 | 詳細 |
---|---|---|
class::pahooScraping | ||
__construct | コンストラクタ | |
__destruct | デストラクタ | |
isJapanese | 使用言語が日本語かどうかを判定する | |
setLanguage | 使用言語を設定する. | |
isError | エラーが発生しているかどうかを取得する. | |
getError | エラー番号を取得する. | |
getErrorMessage | エラー・メッセージを取得する. | |
resetError | エラー状態をリセットする. | |
isphp8over | PHP8以上かどうか検査する | |
evalXPath | 指定したXPath式を評価し,結果を返す. | |
queryXPath | 指定したXPath式を評価する. | |
getTitle | titleを取得 | |
getDescription | descriptionを取得 |
バージョン | 更新日 | 内容 |
---|---|---|
1.5.0 | 2024/01/28 | exitIfExceedVersion() 追加 |
1.4.2 | 2024/01/28 | exitIfLessVersion() メッセージ修正 |
1.4.1 | 2023/09/30 | コメントの訂正 |
1.4.0 | 2023/09/09 | $_GET, $_POST参照をfilter_input()関数に置換 |
1.3.0 | 2023/07/11 | roundFloat() 追加 |
解説:初期化処理
29: //プログラム・タイトル
30: define('TITLE', 'DOMDocumentを使ってスクレイピング');
31:
32: //データ入力に関わる関数群:include_pathに配置すること
33: require_once('pahooInputData.php');
34:
35: //PHPバージョン・チェック
36: exitIfLessVersion(MINUMUM_VERSION);
37:
38: //リファラチェック+リリースフラグの設定
39: if (isset($_SERVER['HTTP_HOST']) && ($_SERVER['HTTP_HOST'] == 'localhost')) {
40: define('FLAG_RELEASE', FALSE);
41: define('REFER_ON', '');
42: ini_set('display_errors', 1);
43: ini_set('error_reporting', E_ALL);
44: } else {
45: //リリース・フラグ(公開時にはTRUEにすること)
46: define('FLAG_RELEASE', TRUE);
47: //リファラ・チェック(直リン防止用;空文字ならチェックしない)
48: define('REFER_ON', 'www.pahoo.org');
49: }
50:
51: //表示幅(ピクセル)
52: define('WIDTH', 600);
53:
54: //スクレイピングURL(デフォルト)
55: define('DEF_URL', 'https://www.pahoo.org/e-soul/webtech/php02/php02-41-01.shtm');
56:
57: //スクレイピング処理に関わるクラス:include_pathが通ったディレクトリに配置
58: require_once('pahooScraping.php');
関数 require_once を使って、スクレイピング処理を行うクラス pahooScraping.php を読み込む。include_pathが通ったディレクトリに配置しておくこと。
解説:pahooScrapingクラスとDOMDocumentクラスの使い方
13: class pahooScraping {
14: private $dom; //DOMDocument
15: private $xpath; //DOMXPath
16: private $language; //使用言語(初期値は日本語)
17: private $error; //エラー・メッセージ
18: private $errorTable; //エラー番号 => エラー・メッセージ 一覧
19:
20: /**
21: * コンストラクタ
22: * @param string $contents 解析対象テキスト
23: * @return object /NULL:PHP8未満のため実行できない.
24: */
25: function __construct($contents) {
26: //PHPのバージョンをチェックする.
27: if (! $this->isphp8over()) {
28: $this->error = 111;
29: throw new Exception($this->getErrorMessage());
30: return NULL;
31: }
32: //プロパティの初期値を設定する.
33: try {
34: $this->dom = new DOMDocument();
35: libxml_use_internal_errors(TRUE);
36: @$this->dom->loadHTML($contents);
37: libxml_clear_errors();
38: $this->xpath = new DOMXPath($this->dom);
39: } catch (Exception $e) {
40: $this->error = 121;
41: throw new Exception($e->getMessage());
42: return FALSE;
43: }
44:
45: //エラー番号 => エラー・メッセージ 一覧
46: $this->errorTable = array(
47: 111 => array('PHP8以上が必要です', 'PHP8 or higher is required'),
48: 121 => array('DOMエラーです', 'DOM error'),
49: 999 => array('不明のエラー', 'unknown error'),
50: );
51: }
まず、pahooScrapingg クラス内で使用するプロパティ $dom, $xpath, $error を宣言する。
コンストラクタは、__construct によって定義する。引数は、クラスを呼び出した時の引数である。ここでは解析対象のテキストを引数とする。戻り値はない。
次に DOMDocumentクラスの使い方だが、その前に DOM について簡単に説明しておこう。
DOM とは Document Object Model の略で HTML や XML 文書をオブジェクトとして扱えるようにしたモデルのことだ。モデルというと分かりにくいのだが、要するに、HTMLやXMLをツリー構造(階層構造)のデータとして扱うことができるようになり、タグや属性名を指定して、目的のコンテンツを読み込んだり編集したりする手段を提供してくれる。
たとえば、<title> タグの内容を取得したり、<a> タグで指し示すリンクを全て取得する、といった処理が簡単にできるようになる。スクレイピングするのに、打って付けの仕組みだ。
コンストラクタで DOMDocument インスタンスを生成したら、DOMDocument::loadHTML を使って文字列からHTMLを読み込む。
DOM のエラー(例外)発生時に対応して、例外を返すようにしている。
ここで、文字コードに注意しなければならない。
DOMDocument::loadHTML は、HTML文書に記載されている文字コードセットを解釈しないようで、UTF-8などの日本語文字が文字化けを起こす。そこで、DOMDocument::loadHTML に渡す前に、関数 mb_convert_encoding を使って HTML-ENTITIES にエンコードしてやる。こうすることで、日本語文字などは16進数に変換されるので、文字化けを起こすことはなくなる。
53: /**
54: * デストラクタ
55: * @return なし
56: */
57: function __destruct() {
58: unset($this->dom);
59: unset($this->xpath);
60: }
解説:XPath式の使い方
129: /**
130: * 指定したXPath式を評価し,結果を返す.
131: * @param string $e XPath式
132: * @return DOMNodeList/FALSE:評価失敗
133: */
134: function evalXPath($e) {
135: return $this->error ? FALSE : $this->xpath->evaluate("string({$e})");
136: }
147: /**
148: * titleを取得
149: * @return titleの内容
150: */
151: function getTitle() {
152: return $this->evalXPath('/html/head/title');
153: }
155: /**
156: * descriptionを取得
157: * @return descriptionの内容
158: */
159: function getDescription() {
160: return $this->evalXPath('/html/head/meta[@name="description"]/@content');
161: }
PHPでは、DOMXPath クラスを使う。コンストラクタで、DOMXPath でオブジェクトを生成するところまでは実行している。
次に、DOMXPath::evaluate を使ってXPath式の評価(検索)をしていく。そのためのメソッド evalXPath を用意した。
titleタグの内容を取り出すメソッド getTitle と、'meta name="description" content=' の内容を取り出すメソッド getDescription を用意した。
XPath式の書き方だが、'/' は階層を示す。
titleタグは 'html→head' の階層にあるので、'/html/head/title' と表記する。これにDOMXPath::evaluateを適用すると、titleタグの内容を取得できる。
'meta name="description" content=' をXPath式で表すと、'//meta[@name="description"]/@content' となる。XPath式で、条件は [...] に記載する。属性からノードを選択する場合には、名前の前に '@' を付ける。
XPath式の書き方は「XPath」(システムエンジニアのスキルアップ)が詳しい。
参考サイト
- DOMDocumentクラス:PHP公式
- DOMXPath クラス:PHP公式
- XPath:システムエンジニアのスキルアップ
PHPバージョン5以上では、HTMLやXMLドキュメントをオブジェクトとして扱うことができる DOMDocumentクラスが用意されている。
そこで今回は、DOMDocumentクラスを使ってスクレイピングを行ってみることにする。他のプログラムでも利用できるよう、DOMDocumentクラスを利用する形のユーザー・クラス pahooScraping を用意した。
(2023年9月18日)pahooScrapingクラスに変更