質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
XPath(XML Path)

XML Path Language (XPath; XMLパス言語)は、マークアップ言語 XML に準拠した文書の特定の部分を指定する言語構文の事をいいます。XPathはXMLとは別の構文を使用します。XMLドキュメントの抽象、論理ストラクチャ上で動作します。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

Q&A

解決済

1回答

758閲覧

xpathの評価で複数の要素が一致しても、全て結合された1つの要素が返る

Praline

総合スコア46

XPath(XML Path)

XML Path Language (XPath; XMLパス言語)は、マークアップ言語 XML に準拠した文書の特定の部分を指定する言語構文の事をいいます。XPathはXMLとは別の構文を使用します。XMLドキュメントの抽象、論理ストラクチャ上で動作します。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

0グッド

0クリップ

投稿2022/04/27 18:06

前提

phpを用いたwebサイトのスクレイピングにおいて、
xpathの評価で一致した要素が全て結合された状態で(1つのDOMNodeListが)出力されます。
目的としては一致した要素をそれぞれ持つDOMNodeListを返したいです。

実現したいこと

https://mtg.bigweb.co.jp/cards/buying-filter?big_keyword=black+lotus
上記サイトの検索結果一覧から、
<div class="row imageview">~</div>内の子要素の<div>~</div>を一覧として取得したい。

発生している問題・エラーメッセージ

php

1 $url = 'https://mtg.bigweb.co.jp/cards/buying-filter?big_keyword=black+lotus'; 2 3 //与えたurlからDOMXPathのインスタンスを返す関数。内容は省略。 4 $html = callSoloCURLProcess($url); 5 6 //取得したいdiv一覧の親要素をclass名から一意に定め、その子要素全てを取得 7 $xroot = $html->query('//div[@class="row imageview"]/div'); 8 9 //本来であればここで要素数が8個(質問時点)となる 10 echo '要素数'.$xroot->length.'個<br/>'; 11 echo '----------------------<br/>'; 12 13 foreach($xroot as $li){ 14 echo $li->nodeValue.'<br/>'; 15 echo '----------------------<br/>'; 16 }

結果

要素数1個 ---------------------- UGL:アングルード / Unglued Blacker Lotus 英2,000円 詳細 【英】2,000円 買い取りに追加 2ED:アンリミテッド / Unlimited Edition Black Lotus 英2,500,000円 詳細 【英】2,500,000円 買い取りに追加 LEB:ベータ / Limited Edition Beta Black Lotus 英6,500,000円 詳細 【英】6,500,000円 買い取りに追加 LEA:アルファ / Limited Edition Alpha Black Lotus 英15,000,000円 詳細 【英】15,000,000円 買い取りに追加 1ページ目/1ページ(全:4件) < 前へ 次へ > ----------------------

試したこと

試しに最初の要素のxpathを開発者ツールからコピーし実行すると、上記の要素に加え別の要素も出力されます。

//*[@id="main_wrap"]/div/div[1]/div[2]/div[2]/div/div/div[1]
上記サイトであれば「UGL:アングルード」というタイトル行に相当。この場合以下のように出力される。

---------------------- UGL:アングルード / Unglued Blacker Lotus 英2,000円 詳細 【英】2,000円 買い取りに追加 2ED:アンリミテッド / Unlimited Edition Black Lotus 英2,500,000円 詳細 【英】2,500,000円 買い取りに追加 LEB:ベータ / Limited Edition Beta Black Lotus 英6,500,000円 詳細 【英】6,500,000円 買い取りに追加 LEA:アルファ / Limited Edition Alpha Black Lotus 英15,000,000円 詳細 【英】15,000,000円 買い取りに追加 1ページ目/1ページ(全:4件) < 前へ 次へ > ---------------------- ■送料について 買取送料、手数料はお客様のご負担となります。 買取内容が折り合わなかった場合の返送料金はお客様のご負担となります。 ■代金の送金について 代金は銀行、または郵便口座への振込みとなります。 銀行、郵便局の口座をお持ちで無い方は当店のカード買取をご利用になれません。 ■カードを送っていただく時に カードが折れたり、曲がったりしないような状態で送って下さい。 必ず御名前、ご住所、電話番号を御明記下さい。 ----------------------

仮説

xpathの挙動について詳しくなく、また以下のような仮説を立てたものの、同様の現象や説明に行き着かなかったため、質問させていただきました。

  • 仕様として、xpathでdivを評価した場合、複数箇所がヒットしても1つの要素として出力される?
  • before、afterなどの疑似要素が階層として評価されるため、一覧ではなく1つの要素として出力される?

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

htmlのソースを見ると以下のようにhtmlが崩れているようです。

html

1<div><h2><div></h2></div>

このような状態では正しく処理できないので、取得したhtmlを正しい構文に補完してから処理してください。
(例えば文字列として</h2>の直前に</div>を差し込む。)
他にも崩れている箇所があるかもしれません。

もしくは他のclass等で取得できないかご検討ください。

投稿2022/04/28 00:10

tabuu

総合スコア2449

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Praline

2022/04/28 15:25

サイト側のhtmlが壊れているは完全に想定外でした… 指摘の通り取得したhtmlを修正することで対応できました。ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問