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

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

新規登録して質問してみよう
ただいま回答率
85.48%
スクレイピング

スクレイピングとは、公開されているWebサイトからページ内の情報を抽出する技術です。

XPath(XML Path)

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

PHP

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

Q&A

解決済

2回答

4315閲覧

DOMXPathでスクレイピングしようとしているのですが、知識不足でエラーを解決できません。

yonaja

総合スコア20

スクレイピング

スクレイピングとは、公開されているWebサイトからページ内の情報を抽出する技術です。

XPath(XML Path)

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

PHP

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

0グッド

0クリップ

投稿2018/09/25 02:12

編集2018/09/25 02:43

前提・実現したいこと

phpでブックオフオンラインのwebスクレイピングをしようとしています。
DOMXPathを利用しスクレイピングしようとしているのですが、特定の要素に限り取得が上手くできません。
自分なりの多くの方々のブログなどを参考にしてプログラムを作ってブックオフオンライン以外のサイトではうまくいくサイトもありました。
プログラミング初心者のため自分で調べて色々試したのですが解決できなかったので、どなたか教えていただけませんでしょうか。
専門用語すら、あやふやなため質問内容が伝わっているか不安です。

スクレイピングしたいページのURLは
http://www.bookoffonline.co.jp/display/L001,q=%2582%25A0%2582%25CC%2589%25D4

スクレイピングしたい要素のxpathは

xpath

//*[@id="resList"]/form/div[4]/div[3]/div[1]/div[2]/table/tbody/tr[2]/td

になります。
ちなみに上記のxpathの要素の中身は以下のようになっています。
この中の¥128を取得したいです。


要素の中身

<td class="mainprice"> ¥128 <span class="price_tax"> (税込) </span> <span> 定価より ¥386 おトク! </span> <th class="tab01"> 中古価格 </th> </td>

実行しているphpプログラムは以下の通りです。

該当のソースコード

php

1 <?php 2 3 /* HTML特殊文字をエスケープする関数 */ 4function h($str) { 5 return htmlspecialchars($str, ENT_QUOTES, 'UTF-8'); 6} 7 8if (1) { 9 // コンテンツを取得 10 $ch = curl_init(); 11 curl_setopt_array($ch, [ 12 CURLOPT_URL => 'http://www.bookoffonline.co.jp/display/L001,q=%2582%25A0%2582%25CC%2589%25D4', 13 CURLOPT_RETURNTRANSFER => true, 14 CURLOPT_FOLLOWLOCATION => true, 15 CURLOPT_AUTOREFERER => true, 16 CURLOPT_USERAGENT => 'Mozilla/5.0', 17 CURLOPT_ENCODING => 'gzip', 18 ]); 19 $html = curl_exec($ch); 20 21 // エラーを出さずにDOMDocumentに読み込む 22 $dom = new DOMDocument; 23 @$dom->loadHTML($html); 24 25 $xpath = new DOMXPath($dom); 26 27 $aa[0]=$xpath ->query('//*[@id="resList"]/form/div[4]/div[3]/div[1]/div[2]/table/tbody/tr[2]/td')->item(0)->nodeValue; 28 29 echo $aa[0]; 30} 31?>

$xpath ->queryを実装中に以下のエラーメッセージが発生しました。

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

Notice: Trying to get property 'nodeValue' of non-object in C:\xampp\htdocs\tatsuki\title.php on line 27

該当のソースコード

php

1 $aa[0]=$xpath ->query('//*[@id="resList"]/form/div[4]/div[3]/div[1]/div[2]/table/tbody/tr[2]/td')->item(0)->nodeValue;

試したこと

xpath->queryがいけないのかと思い、以下のページを参考にxpath->evaluateも使ってみましたが上手く行きませんでした。

https://qiita.com/mpyw/items/c0312271819baee09132#domnodelist-%E3%82%AF%E3%83%A9%E3%82%B9

https://qiita.com/mpyw/items/0454c46b7c1cc06ef5c8

正直xpath->queryとxpath->evaluateの違いは理解しておりません。
ちなみにxpath->evaluateを使用したときは、xpath->queryのところを
変更しました。プログラムは以下の通りです。

該当のソースコード

php

1<?php 2 3 /* HTML特殊文字をエスケープする関数 */ 4function h($str) { 5 return htmlspecialchars($str, ENT_QUOTES, 'UTF-8'); 6} 7 8if (1) { 9 // コンテンツを取得 10 $ch = curl_init(); 11 curl_setopt_array($ch, [ 12 CURLOPT_URL => 'http://www.bookoffonline.co.jp/display/L001,q=%2582%25A0%2582%25CC%2589%25D4', 13 CURLOPT_RETURNTRANSFER => true, 14 CURLOPT_FOLLOWLOCATION => true, 15 CURLOPT_AUTOREFERER => true, 16 CURLOPT_USERAGENT => 'Mozilla/5.0', 17 CURLOPT_ENCODING => 'gzip', 18 ]); 19 $html = curl_exec($ch); 20 21 // エラーを出さずにDOMDocumentに読み込む 22 $dom = new DOMDocument; 23 @$dom->loadHTML($html); 24 25 $xpath = new DOMXPath($dom); 26 27 //$aa[0]=$xpath ->query('//*[@id="resList"]/form/div[4]/div[3]/div[1]/div[2]/table/tbody/tr[2]/td')->item(0)->nodeValue; 28 29 $b = $xpath->query('//*[@id="resList"]/form/div[4]/div[3]/div[1]/div[2]/table/tbody')->item(0); 30 $aa[0] = $xpath->evaluate('string(.//tr[2]/td)', $b); 31 32 echo $aa[0]; 33} 34?>

エラーメッセージはありませんが、全く関係ない要素が取得されます。
知識がなさすぎるためとんちんかんではありますが、どなたか教えてください。
宜しくお願いします。

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

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

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

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

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

m.ts10806

2018/09/25 02:16

コードブロックは何回でも使えるので都度入れてもらえますか?どこがコードでどこが本文かわかりづらくなります。あと、当該サイトはスクレイピング大丈夫なのでしょうか?実際に画面開くことなくアクセスが可能でサイトへの無用な負荷にもつながるため、利用規約で禁じているところも少なくないです。
m.ts10806

2018/09/25 02:17

URLもマークダウンのリンク機能を利用してください
yonaja

2018/09/25 02:33

コードブロックの件は大変失礼いたしました。スクレイピングが利用規約に触れるとのご指摘ありがとうございます。確認したところ、規約等に「スクレイピングは禁止」もしくは「プログラムによる自動取得は禁止」に類する文章はありませんでした。
m.ts10806

2018/09/25 02:40

質問は編集可能なので適宜ご対応いただければと。 「禁止事項」のところがかなりグレーな書き方しているので微妙ですね。あくまでローカルで学習のためだけにとどめておいたほうが良いかなと。もし公開するつもりなのであれば事前に問い合わせをしておけば確実です。
yonaja

2018/09/25 02:44

修正しました。初めて使ったので読みにくい質問で申し訳ございませんでした。公開する予定はありません。ですがご指摘の通り問い合わせしてみることにします。ありがとうございました。
guest

回答2

0

ベストアンサー

php

1$aa[0]=$xpath ->query('//*[@id="resList"]/form/div[4]/div[3]/div[1]/div[2]/table/tr[2]/td')->item(0)->nodeValue;


¥128(税込)定価より ¥386 おトク!が取れます。

多分chromeのcopyasxmlをしたのだと思いますがtbodyはchromeが解釈して追加したもので、ソースのhtmlにはそのタグはないので、取れなかったんでしょう。

投稿2018/09/25 02:30

papinianus

総合スコア12705

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

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

0

ブラウザで、そのページのHTMLソースを表示させて、そのXPath記述でちゃんと目的の要素にたどり着けるか確認して下さい。
tbodyが実際のHTMLにないというのがありがちです。

//td[@class="mainprice"]の方が良いのでは?複数あるかも知れませんが。

投稿2018/09/25 02:31

otn

総合スコア84529

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問