プログラミングTweet前回GASライブラリのParserを使用して、GASからWebスクレイピングを行う方法について書きました。Script)でスクレイピングを行い、Amazonの商品一覧ページから「タイトル」と「価格」をスプレッドシート上に取得する処理を書いてみたので手順を残しておきます。対象のページと結果まず今回作成した処理でどの様な結果が得られるのかを説明します...あれから幾つかのサイト向けにスクレイピングツールを作成していたのですが、実際使い出すとParserは思った以上に不便で、サイトの構成にもよりますが目的のデータをピンポイントに抽出するというのは意外と難しい事が分かりました。前回の記事ではAmazonの商品一覧ページから商品名と価格を抜き出しましたが、あの様に綺麗に抜き出せる方が稀かもしれません。考えるとAmazonは良いサンプルでしたね。今回はParserとプラスアルファを組み合わせて、少し取得が難しい(と思われる)データの取り方を実際のコード例とあわせて紹介してみたいと思います。まとめ属性に固有の値が使われているタグから商品名のみを抜き出す以下は駿河屋の販売商品一覧の画面です。このページから『商品名』と『販売価格』の2つの値を抽出する処理を組むケースを例にします。該当部分のhtmlソースを見てみます。class="item_box">...</div>この「item_box」は一覧の中の横1列部分にあたります。その下に「item」クラスが続いており、こちらに商品一つ一つの情報が記述される形となっています。このitemの中身を更に掘り下げてみます。itemクラスの内部はこの様な構造になっています。ターゲットは赤枠の2箇所です。href=”/product/detail/185172560′′>」toは「</a>」といった感じです。・・・もちろん”この商品の場合”は上記の書き方で問題無いのですが、fromに含まれている「185172560」という数値は明らかに商品IDですよね。いう事は商品が変わればこの部分の数値も変わってしまう事になります。これでは纏めてデータを抽出する事ができないため、別の値を指定しなければいけません。その前後に何か使えそうな文字列が無いかどうかを見てみると・・・ありますね。href=”/product/detail/185172560′′>...</a></p>このtitleのクラスが設定されているPタグあたりが汎用的に使えそうです。このPタグで抽出してしまうと、Pタグ内に余計なaタグが残ってしまいますので、取り除く処理も追加して以下の様にします。titleArray.map(RemoveHTMLTag);これで商品名のみの配列を取得する事ができます。※RemoveHTMLTagの中身は好きな処理で構わないので今回は紹介しません正規表現で抽出する場合ちなみに以下の正規表現を使えば、ピンポイントで商品名のみを抽出することが可能です。href=”\/product\/detail\/.*>(.*?)<\/a>こっちの方がシンプルだし良さそうではあるのですが・・・価格抽出の場合は正規表現だけでは難しいんですよね。「末尾に”円”を含む0~9の整数とカンマで構成される値」という感じの正規表現を使えば取れる事は取れるのですが、「品切れ」のケースが存在しその場合は整数無しの文字列のみである事、この後実装する買取ページの場合はまた表記が変わることなどなど・・・判定式と組み合わせてあれこれする必要があります。正規表現で値をうまく取れない商品が一つでも混じっていた場合、抽出した配列の要素数が商品名と価格で一致しないという事になると、出力結果にズレが生じてデータが使えなくなってしまいます。いう訳で、正規表現を使ってもそこまでシンプルにならないので今回は正規表現をメインに使うことはしません。続いては価格の取得です。htmlは以下の通り。600</strong></span>税込</p></div>単純に見れば「<strong>~</strong>」間を抽出すれば良さそうに見えます。実際<strong>タグが使用されているのはこの価格の部分だけですので、ピンポイントで価格を抽出する事ができるのですが・・・先ほども書いた「品切れ」表記のケースが存在するので、このままでは抽出漏れが起こってしまいます。class=”text-red”>~</span>が使えるかと思いきや、「品切れ」の場合はこちらのタグもありません。通常の価格表記と同じく赤文字なんですけどね。class=”price_teika”>~</p>もありません。class=”item_price”>~</div>を指定するしか無い訳ですね。商品名と同様に、抽出した文字列から余計な部分を取り除いていくだけですので、それぞれ以下の様な処理を書いていきます。・「品切れ」という単語が含まれていれば、任意のメッセージを格納する。・検出できなければ通常の価格表記と判断し、<strong>タグ内の文字を抜き出す。コードにするとこんな感じ。priceArray;}これで価格も無事に抽出する事ができました。続いては買取ページから買取価格などの情報を抜き出します。駿河屋の「あんしん買取」のページに進み、どの様な構成になっているかを確認してみます。販売ページとはまたデザインが違いますね。新たに抽出処理を作成する必要がありそうです。ソースを見てみましょう。この並んでいる<tr>タグが各商品データ行になります。中の構成を見てみます。今回は商品名と、矢印部分の価格を取得します。class=”title”>~</d>に囲まれているのが分かると思いますが・・・これどこかで見た事ありますよね?そうです。最初の方で書いた販売ページの構成と同じなんですね。実は商品名だけは処理を使い回す事ができます。価格自体はTDタグに囲まれていますが、その他の要素も全てTDタグが使われています。その上の階層のタグとなるとテーブル行のTRタグのみです。・・・このTRタグ以外使えそうなものは無いので、これを使います。.iterate();from、toの指定はこんな感じですね。bgsell”>」の方が抽出できないのでこの様な指定にしています。価格の要素はTDタグに囲まれていますので、抽出した各データに対してここから更にTDタグ内の文字を抽出する処理を書きます。.iterate();これで各データ行のTD項目内のデータのみを抽出する事ができました。class=”listap」を指定したため、「”>」から始まる文字列になっています。XmlService.parseだとタグが閉じられていなかったり”解析できる形”になっていない場合はエラーになっていましたので、このParserライブラリも何かエラーになるんじゃないの?・・・と思うかもしれませんが、実は全く問題ありません。Parserの中身を見てみると分かるのですが、あのライブラリが中で行っているのは「IndexOfで指定した文字列の開始/終了位置を特定し、substringで切り出す」という単なる文字列操作ですので、タグ閉じされていないだとかツリー構造がどうだとかそういうのは関係無いんです。「Parser」という名前でつい勘違いしそうですけどね。結局、価格抽出のために組んだコードはこちら。・「メールにてお見積」という文字列が含まれていれば価格無し(-)を設定といった感じ。※自分用のアプリなので、変数名や構成が雑なのはスルーして下さいまとめ今回は自分用に作った駿河屋用販売/買取リスト一覧の抽出処理の中身を紹介してみました。”抽出”する部分の処理だけですので、スプレッドシート上に貼り付けたり、次のページに移動する処理は別途用意する必要があります。ちなみにアプリ自体は既に完成しており、今までに10万点以上の商品データを抽出していますが、今の所問題無く抽出する事ができています。気になる実行速度についてですが、100ページ分2400商品で約70秒です。※実行する日時によって差は出ますGASの実行上限が6分と考えても、単純計算で500ページ分のデータは取得できますね。量的にも十分だと思います。GASは使いこなすと本当に便利なので、ぜひ触ってみる事をお勧めします。唐突に思い立ったので善は急げという事で株取引の自動化をやってみようと思います。以前、以下の記事でメルカリをVBAで操作するための方法を書きました。前回は使用できるレスポンスグループの一覧を確認する所まででした。API」を使って試してみ...記事を読む効率の良いスクレイピングを行うためのテクニックと考え方1今回はWebサイトをスクレイピングするにあたって、スクレイピングを効率的に行うための考え方やテクニックについて書いてみようと思います。...記事を読むGASの連想配列の扱い方について(定義、要素の追加、削除)前回は”配列”についての解説を行いましたが、今回は”連想配列”と呼ばれるものの解説を行います。今回で初回のウェブスクレイピングツール編は最後になります。コメントをキャンセルメールアドレスが公開されることはありません。コメントデータの処理方法の詳細はこちらをご覧ください。固定ページ内を検索プロフィール藤美れいん(ふじみれいん)プログラマとして入社後、数年の開発経験を経てフリーへ転職。せどり、ネットショップ運営、パチスロ期待値稼働、プログラム開発等々を経験し今に至る。現在は一時的に復職し、都内某所で活動中。過去に公開したツールなどは、サイト上部のメニューにある「TOOLS」をご覧下さい。プログラムに関する質問、その他ご相談はメールやTwitterからどうぞ。@raine_fujimi※返信は大体数日後になります。返信できない場合もありますので予めご了承下さい。