人力検索はてな
モバイル版を表示しています。PC版はこちら
i-mobile

PHP の simple_html_dom.php で、htmlファイルのタグをすべて取り出して表示させることは可能ですか。
もし、可能であれば、私が作ったプログラムの修正をお願いできると大変助かります。

http://1811way.com/work008/sample10.html
であれば、
<body>タグ以降

<h4><ul><li><h2><ul><li><h3>....

のように表示できれば、と思っています。
*<>は表示できなくても構いません。

1.私の書いたプログラム
require "simple_html_dom.php";
$html = file_get_html('sample1.html');

foreach ($html as $taglist) {
echo $taglist->tag;
}

2.環境:php5.6 Apache2.4 Windows


以上、よろしくお願いします。


●質問者: kohhi
●カテゴリ:ウェブ制作
○ 状態 :終了
└ 回答数 : 2/2件

▽最新の回答へ

1 ● a-kuma3
●200ポイント ベストアンサー

子供のタグにもぐって行くということですよね。
こんな感じでできます。

<?php
require "simple_html_dom.php";

$html = ...

function extract_child_tag($p) {
 $e = $p->first_child();
 while ($e) {
 echo '&lt;' . $e->tag . '&gt;';
 extract_child_tag($e);
 $e = $e->next_sibling();
 }
}

$body_list = $html->find('body');
extract_child_tag($body_list[0]);

タグを囲む < > をくっつけてますが、要らなかったら echo から外してください。


kohhiさんのコメント
お正月に早速回答いただきありがとうございます。いつもすいません。

kohhiさんのコメント
できました。

2 ● TransFreeBSD
●200ポイント

先越されてしまった><
色々書き方はあるので、書いておきます。

<?php
require "simple_html_dom.php";
$html = file_get_html('sample1.html');

function walk($node) {
#if ($node->nodetype <> 1) return;
foreach ($node->childNodes() as $child) {
echo "<".$child->tag.">";
walk($child);
}
}

walk($html->find("body", 0));
echo "\n";

<?php
require "simple_html_dom.php";
$html = file_get_html('sample1.html');

$node = $html->find("body *", 0);
while ($node) {
echo "<".$node->tag.">";
# 子ノードがあればそれを、なければ兄弟ノードを
$next = $node->firstChild() ?: $node->nextSibling();
while (! $next) {
# 子ノードも兄弟ノードもなければ親の
$node = $node->parent();
# 親ノードがbodyに戻っていたら終了
if ($node->tag == "body" )
break;
$next = $node->nextSibling();
# 兄弟ノードが見つかるまでたどる
}
$node = $next;
}

echo "\n";

simple_html_domはその名の通りDOMを扱います。
なのでDOMの知識が必要です。
http://piyo-js.com/05/dom.html
http://www.ajaxtower.jp/js/dom/
http://hakuhin.jp/js/dom.html
やはりjavascriptでの説明が多いのですが、文法が若干違う程度でDOMとしては同じです。
ただ、simple_html_domはDOMのよく使う一部だけの実装なのと、独自名やjqueryの影響が見られますので、適宜読み替えなど必要です。
http://simplehtmldom.sourceforge.net/manual.htm
また、phpのもいくらか参考になります。
http://php.net/manual/ja/class.domnode.php

今後、本格的にDOMを扱う様であれば、phpのDOMのほか、SimpleXMLやXML パーサについても知っておくとお得かも知れません。
http://php.net/manual/ja/class.simplexmliterator.php
http://php.net/manual/ja/example.xml-map-tags.php

[追記]
裏技的なのを。
テキストとbodyタグと全ての閉じタグを消してしまいます。
#コメントは残るかもしれません。

<?php
require "simple_html_dom.php";
$html = file_get_html('sample1.html');

function my_callback($element) {
if ($element->tag == "text" )
$element->outertext = "";
if ($element->tag == "body")
$element->_[HDOM_INFO_BEGIN] = -1;
$element->_[HDOM_INFO_END] = 0;
}

$html->set_callback('my_callback');
echo $html->find("body", 0);
echo "\n";

a-kuma3さんのコメント
そうそう。 simple_html_dom って、DOM の規格から見ると実装は中途半端ですよね。 ただ、Text は邪魔くさいこともあるので、simple_html_dom の実装もありかなあ(php 的に)とは思います <tt>:-)</tt>

TransFreeBSDさんのコメント
jquery参考にしたスクレイプのためのだから、データをとってくる向きには使いやすいですよね。 domやsaxで辿るより、findで絡めて処理したほうがわかりやすい。 xpathとかもあるけどcssセレクタベースの方がわかりやすい。 テキストノードの扱いも、そういうjqueryの様に実用に即した部分がありますね。 ただ、ドキュメントが充実してない(笑) あと、今回のはすべて辿る気なので別の手もありえるかなと。 #->find("*")で全部辿れると思ったら出来なかった><

a-kuma3さんのコメント
>> xpathとかもあるけどcssセレクタベースの方がわかりやすい。 << 確かに。 javascript 方面だと、document.querySelector メソッドが一番 使いやすいです。

kohhiさんのコメント
ご丁寧な回答をいただきありがとうございます。
関連質問

●質問をもっと探す●



0.人力検索はてなトップ
8.このページを友達に紹介
9.このページの先頭へ
対応機種一覧
お問い合わせ
ヘルプ/お知らせ
ログイン
無料ユーザー登録
はてなトップ