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

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

ただいまの
回答率

90.51%

  • PHP

    23997questions

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

  • HTML

    11456questions

    HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

  • スクレイピング

    465questions

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

php getElementsByTagNameでの抽出

解決済

回答 1

投稿

  • 評価
  • クリップ 1
  • VIEW 284

Koh_

score 19

PHP:DomDocumentのGetElementsByTagNameを用いて指定したタグの情報を抽出しようとしています。
指定したタグが存在しない場合のエラー処理をどのようにすればよいか、ご教授ください。

対象とするHTMLの中には同一名のタグ <lowestofferlisting>が複数あります。このタグ中の 
<landedprice>中の<Amount>の内容
<listingprice>中の<Amount>の内容
<shipping>中の<Amount>の内容
を取ってくるのが目的です。ただし、今回一例として以下に示したHTMLは<lowestofferlisting>が4個ありますが、本来対象とするHTML中の<lowestofferlisting>の数は0~4個です。

HTMLは以下です。<lowestofferlisting>が4つあります。

<getlowestofferlistingsforasinresult asin="430946209X" status="Success">
    <allofferlistingsconsidered>true</allofferlistingsconsidered>
    <product>
      <identifiers>
        <marketplaceasin>
          <marketplaceid>A1VC38T7YXB528</marketplaceid>
          <asin>430946209X</asin>
        </marketplaceasin>
      </identifiers>
      <lowestofferlistings>
        <lowestofferlisting>
          <qualifiers>
            <itemcondition>Used</itemcondition>
            <itemsubcondition>Acceptable</itemsubcondition>
            <fulfillmentchannel>Merchant</fulfillmentchannel>
            <shipsdomestically>True</shipsdomestically>
            <shippingtime>
              <max>0-2 days</max>
            </shippingtime>
            <sellerpositivefeedbackrating>95-97%</sellerpositivefeedbackrating>
          </qualifiers>
          <numberofofferlistingsconsidered>1</numberofofferlistingsconsidered>
          <sellerfeedbackcount>95329</sellerfeedbackcount>
          <price>
            <landedprice>
              <currencycode>JPY</currencycode>
              <amount>512.00</amount>
            </landedprice>
            <listingprice>
              <currencycode>JPY</currencycode>
              <amount>164.00</amount>
            </listingprice>
            <shipping>
              <currencycode>JPY</currencycode>
              <amount>348.00</amount>
            </shipping>
          </price>
          <multipleoffersatlowestprice>False</multipleoffersatlowestprice>
        </lowestofferlisting>
        <lowestofferlisting>
          <qualifiers>
            <itemcondition>Used</itemcondition>
            <itemsubcondition>Good</itemsubcondition>
            <fulfillmentchannel>Merchant</fulfillmentchannel>
            <shipsdomestically>True</shipsdomestically>
            <shippingtime>
              <max>0-2 days</max>
            </shippingtime>
            <sellerpositivefeedbackrating>95-97%</sellerpositivefeedbackrating>
          </qualifiers>
          <numberofofferlistingsconsidered>3</numberofofferlistingsconsidered>
          <sellerfeedbackcount>8689</sellerfeedbackcount>
          <price>
            <landedprice>
              <currencycode>JPY</currencycode>
              <amount>544.00</amount>
            </landedprice>
            <listingprice>
              <currencycode>JPY</currencycode>
              <amount>287.00</amount>
            </listingprice>
            <shipping>
              <currencycode>JPY</currencycode>
              <amount>257.00</amount>
            </shipping>
          </price>
          <multipleoffersatlowestprice>False</multipleoffersatlowestprice>
        </lowestofferlisting>
        <lowestofferlisting>
          <qualifiers>
            <itemcondition>Collectible</itemcondition>
            <itemsubcondition>Good</itemsubcondition>
            <fulfillmentchannel>Merchant</fulfillmentchannel>
            <shipsdomestically>True</shipsdomestically>
            <shippingtime>
              <max>0-2 days</max>
            </shippingtime>
            <sellerpositivefeedbackrating>95-97%</sellerpositivefeedbackrating>
          </qualifiers>
          <numberofofferlistingsconsidered>3</numberofofferlistingsconsidered>
          <sellerfeedbackcount>2532</sellerfeedbackcount>
          <price>
            <landedprice>
              <currencycode>JPY</currencycode>
              <amount>832.00</amount>
            </landedprice>
            <listingprice>
              <currencycode>JPY</currencycode>
              <amount>575.00</amount>
            </listingprice>
            <shipping>
              <currencycode>JPY</currencycode>
              <amount>257.00</amount>
            </shipping>
          </price>
          <multipleoffersatlowestprice>False</multipleoffersatlowestprice>
        </lowestofferlisting>
        <lowestofferlisting>
          <qualifiers>
            <itemcondition>Used</itemcondition>
            <itemsubcondition>Good</itemsubcondition>
            <fulfillmentchannel>Merchant</fulfillmentchannel>
            <shipsdomestically>True</shipsdomestically>
            <shippingtime>
              <max>8-13 days</max>
            </shippingtime>
            <sellerpositivefeedbackrating>90-94%</sellerpositivefeedbackrating>
          </qualifiers>
          <numberofofferlistingsconsidered>1</numberofofferlistingsconsidered>
          <sellerfeedbackcount>894</sellerfeedbackcount>
          <price>
            <landedprice>
              <currencycode>JPY</currencycode>
              <amount>6651.00</amount>
            </landedprice>
            <listingprice>
              <currencycode>JPY</currencycode>
              <amount>5945.00</amount>
            </listingprice>
            <shipping>
              <currencycode>JPY</currencycode>
              <amount>706.00</amount>
            </shipping>
            <points>
              <pointsnumber>5</pointsnumber>
              <pointsmonetaryvalue>
                <currencycode>JPY</currencycode>
                <amount>5.00</amount>
              </pointsmonetaryvalue>
            </points>
          </price>
          <multipleoffersatlowestprice>False</multipleoffersatlowestprice>
        </lowestofferlisting>
      </lowestofferlistings>
    </product>
  </getlowestofferlistingsforasinresult>

上のHTMLを対象とすると、以下のphpコードで抽出することができました。HTMLは$domの中に入っています。
しかし以下のコードだと、<lowestofferlisting>が4つ未満の場合エラーが出て処理が止まってしまいます(本来対象とするHTMLの<lowestofferlisting>の数は0~4個なので)。例えば、<lowestofferlisting>が3個の場合、$root_0_3の参照でエラーが出ます。

$root_0 = $dom_->getElementsByTagName("GetLowestOfferListingsForASINResult")->item(0);

$root_0_0 = $root_0->getElementsByTagName("LowestOfferListing")->item(0);      #複数ある中の最初の<lowestofferlisting>を選択
$Amount0_1 = $root_0_0->getElementsByTagName("Amount")->item(0);      #<landedprice>中の<Amonut>を取得
$Amount0_2 = $root_0_0->getElementsByTagName("Amount")->item(1);      #<listingprice>中の<Amonut>を取得
$Amount0_3 = $root_0_0->getElementsByTagName("Amount")->item(2);      #<shipping>中の<Amonut>を取得

$root_0_1 = $root_0->getElementsByTagName("LowestOfferListing")->item(1);      #複数ある中の2番目の<lowestofferlisting>を選択
$Amount1_1 = $root_0_1->getElementsByTagName("Amount")->item(0);      #<landedprice>中の<Amonut>を取得
$Amount1_2 = $root_0_1->getElementsByTagName("Amount")->item(1);      #<listingprice>中の<Amonut>を取得
$Amount1_3 = $root_0_1->getElementsByTagName("Amount")->item(2);      #<shipping>中の<Amonut>を取得

$root_0_2 = $root_0->getElementsByTagName("LowestOfferListing")->item(2);      #複数ある中の3番目の<lowestofferlisting>を選択
$Amount2_1 = $root_0_2->getElementsByTagName("Amount")->item(0);      #<landedprice>中の<Amonut>を取得
$Amount2_2 = $root_0_2->getElementsByTagName("Amount")->item(1);      #<listingprice>中の<Amonut>を取得
$Amount2_3 = $root_0_2->getElementsByTagName("Amount")->item(2);      #<shipping>中の<Amonut>を取得

$root_0_3 = $root_0->getElementsByTagName("LowestOfferListing")->item(3);      #複数ある中の4番目の<lowestofferlisting>を選択
$Amount3_1 = $root_0_3->getElementsByTagName("Amount")->item(0);      #<landedprice>中の<Amonut>を取得
$Amount3_2 = $root_0_3->getElementsByTagName("Amount")->item(1);      #<listingprice>中の<Amonut>を取得
$Amount3_3 = $root_0_3->getElementsByTagName("Amount")->item(2);      #<shipping>中の<Amonut>を取得

   
エラー文

Fatal error: Uncaught Error: Call to a member function getElementsByTagName() on null in...

$root_0_3の参照でnullとなっているためエラーが出たと考え、回避するようにif文を入れてみましたが、同様のエラーが出ました。どのようにすればエラー回避できるのでしょうか。どなたかご教授ください。

if (!empty($root_0->getElementsByTagName("LowestOfferListing")->item(3))) {
$root_0_3 = $root_0->getElementsByTagName("LowestOfferListing")->item(3);
$Amount3_1 = $root_0_3->getElementsByTagName("Amount")->item(0);
$Amount3_2 = $root_0_3->getElementsByTagName("Amount")->item(1);
$Amount3_3 = $root_0_3->getElementsByTagName("Amount")->item(2);
} else {
echo "No data found";
}
  • 気になる質問をクリップする

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

+1

指定したタグが存在しない場合のエラー処理をどのようにすればよいか、ご教授ください。

_0 _1 とか書いている時点でアンチパターンだと思ってください。こういうのはループ処理で書くべきです。

また,質問の方針通りに回答してもいいですが,そもそもXPath使ったほうが圧倒的にラクなので方針変えましょう。

PHPネイティブのDOMによるスクレイピング入門 - Qiita

とりあえずこれを一通りごらんになって,ソースコードを書きなおしてみてください。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

同じタグがついた質問を見る

  • PHP

    23997questions

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

  • HTML

    11456questions

    HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

  • スクレイピング

    465questions

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