• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:PHPスクレイピングが上手くいきません)

PHPスクレイピングできない!勉強方法と指定方法

このQ&Aのポイント
  • PHP Simple HTML DOM Parser を使って、スクレイピングをやってみようと試行錯誤している最中なのですが、上手く出来なくて困っています。
  • 具体的に分からないのは、文字列の指定方法や価格の表示方法です。
  • どのように勉強すれば理解できるか、指定方法や表示方法について教えて頂けると助かります。

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

  • ベストアンサー
  • bm_hiro
  • ベストアンサー率51% (200/388)
回答No.3

文字数固定の決め撃ちはやめたほうがいいですね。 下記は とりあえず、今回のケースでのみ動くという程度のもの。 正直、俺は正規表現を良く知らないので、もっといいやり方があると思う。 foreach($html->find('table.infoBox') as $item); $str = $item->plaintext; $DimData = explode(" " , trim($str)); foreach($DimData as $i => $dat) { list($num , $price) = mb_split("個" , $dat); $price = preg_replace("/[^0-9]/" , "" , $price); print "$num 個 $price 円<br>\n"; }

machahiko00
質問者

お礼

ご回答ありがとうございます。 まだ何故これでスクレイピングされるのか理解出来ていませんが、 おかげさまで方向性が見えましたので、早速勉強開始しました。 こちらをベストアンサーとさせて頂きます。 回答して頂いた皆さん、ありがとうございました。

全文を見る
すると、全ての回答が全文表示されます。

その他の回答 (2)

  • bm_hiro
  • ベストアンサー率51% (200/388)
回答No.2

一応確認。 teraのRMTのページですよね? んで、価格のところ(1個以上~10個以上)を取得したいんですよね? 一応、↓で結構絞り込めます。 foreach($html->find('table.infoBox') as $item) { echo $item->plaintext . " <br>\n"; } 後は、自分で加工して、切り出すとかしたほうが楽かもしれません。

machahiko00
質問者

お礼

ご回答ありがとうございます。 >後は、自分で加工して、切り出すとかしたほうが楽かもしれません。 試してみました。↓ foreach($html->find('table.infoBox') as $item); $str1 = $item->plaintext; $substr1 = substr($str1,37,3); echo $substr1; このようにすれば目的の数値だけを取り出せるのですが、 こうすると価格の桁数の変動などに非常に弱くなってしまいます…。 うまい加工方法などありましたら教えて下さると助かります。

全文を見る
すると、全ての回答が全文表示されます。
  • bm_hiro
  • ベストアンサー率51% (200/388)
回答No.1

> foreach($html->find('ここの指定方法が分かりません') as $item); んー。。。正直、そちらが参考にしたサイトに書いてあるとおりです。 $item->plaintext だと「ここの指定方法が分かりません」の部分に、取り出したいHTMLタグを指定すれば、そのタグで囲まれた部分のテキストが取れてきます。 以下は俺が試してみたもの。 ○ hoge.php ------------------ <?php include_once('../simple_html_dom.php'); $html = file_get_html('./hk.htm'); foreach($html->find('div[id]') as $item) { echo $item->plaintext . "<br>\n"; } ?> ------------------ ○ hk.htm ------------------ <html> <body> <div id=hk>残念。</div> <div>それは私の</div> <div id=oi>おいなりさんだ</div> </body> </html> ------------------ 俺が試してみたものは、「DIV で ID のあるもの」という条件でスクレイピングしているから、元々のHTMLとPHPでスクレイピングしたものでは、表示が変わる。 HTMLのほうの「それは私の」の部分は IDを指定していないから、スクレイピングのほうではスルーされる。 ↓これを foreach($html->find('div[id]') as $item) { ↓こう変更すると、 foreach($html->find('div[id=oi]') as $item) { 「おいなりさんだ」しか表示しなくなります。 > 何をどう勉強すれば理解出来るようになるのでしょうか。 俺の場合は、概ね「トライアル&エラー」 日本語で言ったほうが短くて済む「試行錯誤」 幸い この PHP Simple HTML DOM Parser には、丁寧に example がついてた。 確実に動くサンプルがあるんだから、それを自分でいじってみて、何がどう変わるか見て、それで覚える感じですかね。 > また、http://www.iimy.co.jp/item/p-33969.htmlに記載されている~ うん。ごめん。面倒くさくなったから他の人に任せます。

machahiko00
質問者

お礼

回答、ありがとうございます。 >俺の場合は、概ね「トライアル&エラー」 挙げてくださった例だと非常にシンプルで分かりやすいのですが、 実際にリンク先サイトのソースを見てトライしてみると まったく思い通りに抽出してくれなくて戸惑っています。 スクレイピングしたいサイトが30サイト以上あるので、 行き当たりばったりではなく、テンプレートな指定方法以外の テクニックみたいなものが欲しかったというのもあるかもしれません。 exampleは普通に見逃していました…。 さっそく弄っています。ありがとうございます。 引き続きご回答お待ちしています。 リンク先サイトを例にした場合、文字列の指定方法はどのようなものが 最適かを教えてもらえると、参考になりとても助かります。

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • PHPの記述について

    質問させていただきます。 PHP Simple HTML DOM Parserを用いて 以下のような記述で ブラウザにより結果は表示されます。 この結果を テキストファイル(たとえばtest.txt)にして同じでディレクトリに 保存するにはどのような記述になりますか? よろしくお願いいたします。 <?php require_once('simple_html_dom.php'); $html = file_get_html('http ://hogehoge'); foreach($html->find('li[class=hogehogehoge]') as $element) echo $element->plaintext."<br />" ?>

    • ベストアンサー
    • PHP
  • スクレイピングPHPにおける複数spanについて

    外部のホームページのソースを拾いRSS化するPHPを作成しました。 ***************************************** 外部ホームページ http://hoge.com/index.html ***************************************** <html> <table class="Table100"> <tr> <th class="Name"><h1>えんどう豆</h1></th> <td class="Price">254</td> <td class="maker"> <span class="a1">メーカー</span> <span class="a2">遠藤農園</span> </td> </tr> </table> </html> ***************************************** スクレイピングPHP http://hagedebu.jp/index.php  ***************************************** <?php class SimpleXMLExtended extends SimpleXMLElement { public function addCData($data) { $dom = dom_import_simplexml($this); $dom->appendChild($dom->ownerDocument->createCDATASection($data)); } } $xml = new SimpleXMLExtended('<rss version="2.0"></rss>'); $channel = $xml->addChild('channel'); $channel->addChild('title', 'TEST RSS'); $dom = new DOMDocument; @$dom->loadHTMLFile('http://hoge.com/index.html'); $xpath = new DOMXPath($dom); foreach ($xpath->query('//*[@class="Table100"]') as $node) { $item = $channel->addChild('item'); $item->addChild('description')->addCData(implode('<br>', [ $xpath->evaluate('string(.//*[@class="Name"]/h1)', $node), $xpath->evaluate('string(.//*[@class="Price"])', $node), $xpath->evaluate('string(.//*[@class="maker"]/span)', $node), ])); } header('Content-Type: application/xml; charset=utf-8'); $xml->asXML('php://output'); ************************************************ 問題点 このPHPでは、 えんどう豆 254 メーカー と表示されてしまいます。 <td class="maker"> <span class="a1">メーカー</span> <span class="a2">遠藤農園</span> </td> class="makerに複数のspanが入っているため、2つめのspanを認識しません。 当方が表示させたいのは下記のようにspanを両方とも表示させたいです。 またはひとつしか表示させることができない場合は、「メーカー」ではなく「遠藤農園」を優先表示させたいです。 このように表示させるためにはどうすればよいでしょうか? 希望表示 えんどう豆 254 メーカー 遠藤農園 または えんどう豆 254 遠藤農園 よろしくお願いいたします。

    • ベストアンサー
    • PHP
  • SimpleHTMLDOMParserについて

    PHP Simple HTML DOM Parserを最近使い始めて まだ基本的な部分しかわからず困っています。 現在ショッピングサイトのデータを自サイトに表示するために 取得を行なっているのですが ショッピングサイトのテーブルにクラス属性などがあまり無く 指定した物を取得する方法で行き詰っています。 属性などが無いので foreach ($html->find('td[align=center] a') as $element) { array_push($test, $element); } 等で取得を行い商品とタイトルと価格等は表示が行えるようになりました。 しかし、必要のないものまで含まれてしまい その部分だけを除外したいのですが、除外方法等はありませんでしょうか? イメージ的には foreach ($html->find('td[align=center] a, td[class!=jogai]') as $element) { array_push($test, $element); } このようにすればjogaiのクラス属性を除けるかと思ったのですが 違ったようでうまくいきません・・・ 結果として、tdのalign属性=centerを取得してtdにjogaiのクラス属性が付いているものは取得しない と言う結果を望んでいます。 お分かりになる方がいましたらご教示お願いいたします。

    • 締切済み
    • PHP
  • HTML DOM Parserで取得できない

    PHP Simple HTML DOM Parserでスクレイピングをしているのですが、 $row = <<<EOF <a href="http://yahoo.co.jp">yahoo</a> EOF; $row = str_get_html($row); echo $row; // 表示される echo $row->href; // 表示されない 上記の表示されない部分はどうやったらできますでしょうか? よろしくお願いします。

    • ベストアンサー
    • PHP
  • PHPで以下のサイトのrssの情報を獲得したいのですが、なぜか<ite

    PHPで以下のサイトのrssの情報を獲得したいのですが、なぜか<item>を獲得できません。 rss: http://twib.jp/rss phpコード: $rss =simplexml_load_file('http://twib.jp/rss'); print_r($rss); $title =$rss->channel->title; echo $title; foreach ($rss->channel->item as $item) { echo $item->title; echo $item->description; echo $item->link; echo $item->pubDate; } どなたか、どこを直せばよいか教えていただけないでしょうか。

    • 締切済み
    • PHP
  • PHPのDOMでXML読み込もうとしているのですが...

    PHPのDOMでXML読み込もうとしているのですが、getElementsByTagNameがうまくいきません。 PHPのバージョンは5です。 コードは以下のとうりです。 $document = new DomDocument('1.0'); $document -> Load('test.xml'); $items = $document -> getElementsByTagName('item'); if(!is_null( $items)){ echo count($items); echo "ok"; } XMLにitemノードは3つあるので、 echo count($items); で 3が返ってくると思うのですが、1しか返ってきません。 $items -> value でも何も表示されません。 でも cho "ok"; の ok は表示されます。 すみません。どなたかどこが間違っているのか教えていただけると助かります。

    • ベストアンサー
    • PHP
  • 日付をPHPに渡す

    下記のようなPHPとHTMLがあります。 HTMLに日付を指定できるフォームを設置しており、ここに入力されたデータを、 PHPの日付の部分に渡せるようにしたいと思っております。 <?PHP //言語設定、内部エンコーディングを指定する mb_language("japanese"); mb_internal_encoding("UTF-8"); //ライブラリ include('googleanalytics.class.php'); //アカウント $ga = new GoogleAnalytics('ID','PW'); $ga->setProfile('ga:GAID'); //日付指定 $today1 = mktime(0, 0, 0, date("m"), date("d")-30, date("Y")); $today2 = mktime(0, 0, 0, date("m"), date("d")-30, date("Y")); $g1 = date("Y-m-d", $today1); $g2 = date("Y-m-d", $today2); $ga->setDateRange($g2,$g1); //読み込み $report = $ga->getReport( array('dimensions'=>urlencode('ga:keyword'), 'metrics'=>urlencode('ga:visits,ga:pageviews'), 'sort'=>'-ga:pageviews' ) ); //表示 echo "<html><head><meta content='text/html; charset=UTF-8' http-equiv='Content-Type'/>"; echo "</head><body>"; echo "キーワード:セッション数:ページビュー数<BR>- - - - - <BR>"; foreach( $report as $d => $m ){ echo $d; foreach( $m as $a => $b ){ echo " : ".$b; } echo "<BR>"; } echo "</body></html>"; ?> <html> <br> ■ 期間 <form action="gaapisample.php" method="post"><label>日付(type="date1"):<input type="date" name="date"></label> <br> <form action="gaapisample.php" method="post"><label>日付(type="date2"):<input type="date" name="date"></label> <input type="submit" value="期間設定"></form> </html>

    • 締切済み
    • PHP
  • phpで重複チェック

    phpの重複チェック phpで配列の重複データをチェックして、重複しているデータを表示しようとしています。 foreach ($arry as $key => $value) { $err_count = 0; foreach ($arry as $key => $value2) { if ($value == $value2) { $err_count++; if ($err_count >= 2) { echo "重複".$value2; } } } } としているのですが、 同じモノが2回表示されて困っています。 重複しているデータは一回だけ表示したいのですが、 なにか方法ないでしょうか?

    • ベストアンサー
    • PHP
  • phpでの変数の作り方をsmartyで実現する方法

    phpでの変数の作り方をsmartyで実現する方法を教えていただきたいです。 簡単な例ですが以下のような場合どうすれば実現できるでしょうか? $Out = array("Out_10"=>"test1","Out_20"=>"test2","Out_30"=>"test3"); $Status_Num = array("10","20","30"); $window->assign('Out',$Out); $window->assign('Status_Num',$Status_Num); [表示] {foreach from=$Status_Num item=Num} <!--ここが分かりません。。--> {/foreach} [実現したい事] phpであれば。。 <?php foreach($Status_Num as $Num):?> <a href=""><?php echo $Out['Out_'.$Num];?></a> <?php endforeach;?> 連想配列のvarを表示させたいのです。。 上記の形をsmartyで実現したいです。 エラー続きで困っています。 どなたか教えてください。 よろしくお願いいたします。

    • ベストアンサー
    • PHP
  • phpについて~<div>;foreach

    PHP初心者です。<div>の中でforeachって使えるのですか? <?PHP require_once 'rss_fetch.inc'; $url = $td[SITEURL]; $rss = fetch_rss($url); $title = $rss->channel['title']; $title = $item[title]; $title = mb_convert_encoding($title, "EUC-JP", "auto"); echo<<<__EOF__ <div class="dt"> <p class="dtTitle"> <a href="{$_SERVER["PHP_SELF"]}?id={$td["ID"]}&amp;url={$td["SITEURL"]}"> {$td["SITENAME"]} </a> {$listCt} {$flgImg} </p> <p class="dtCategory">コミュニティ:{$td["CATEGORY"]}{$FlgTag}</p> $NAME <p class="dtComment">{$img}{$td["COMMENT"]}</p> $ADMINCOMMENT <p class="dtDate">登録日:{$td["REGISTDATE"]}[<a href="regist.php?id={$td["ID"]}">編集</a>]</p> この部分↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ <?php foreach ($rss->items as $item ) { $title = $item[title]; $title = mb_convert_encoding($title, "EUC-JP", "auto"); $url = $item[link]; $date = date("Y/m/d H:i:s", strtotime($item['dc']['date'])); ?> <p class="dtComment"> <li><a href=\"$url\">$title</a>$date</li></p> <?PHP } ?> </div> __EOF__; ?> このような書き方しか思いつかないのですが、 <div>~</div>の中でforeachの使い方を教えてください。

    • 締切済み
    • PHP