カテゴリー
コンピューター

【EC-CUBE】受注ページで数クリックでエクセルに貼れるデータをコピーしたい♪つまり、Chrome ブラウザのコンソールを叩いてJavaScriptでスクレイピングしたい!

本投稿内容を実際に試せる環境

本投稿内容を試すと次のデータが得られます

スクリーンショット 2014-12-31 19.31.01.png

  • 1お届け先1行の形で、お届け先情報、お届け先氏名、購入者情報、購入者氏名、お届日時指定をタブ区切りで出力
  • まとめて選択してエクセルやスプレッドシートに貼り付ければ各セルに別れて貼り付けることができる

本投稿内容を実際に試す方法

  1. Google Chrome を起動
  2. EC-CUBEデモサイト から管理画面に移動し、ログイン
  3. 上部メニューから「受注管理>受注管理」に移動し、「この条件で検索する」で受注一覧を表示
  4. 一覧の中から適当な受注を選択し、「編集」をクリックして受注詳細画面へ移動
  5. Crome デベロッパーツールを起動(Mac なら command + option + i)
  6. デベロッパーツールの上部メニュー「Console」へ移動
  7. 「貼り付ける JavaScript ソース」をコピーし貼り付けて、「enter」キー

結果、次の画像のようにスクレイピングしたデータが表示されますわ。表示データは選択してコピーしてエクセルに貼り付ければ配送先、購入者などが別々のセルに自動でペーストできますの。

スクリーンショット 2014-12-31 19.26.14.png

貼り付ける JavaScript ソース

後からカスタマイズすることを考えて、シンプルな作りにいたしました♪(といいますか、jQuery や JavaScript でできることよくわからなくてこれが限界です><)。

// 表示用変数への引き渡し用変数
var arr = [];

/*
 * 購入者情報
 */
// 郵便番号
var order_zip01 = jQuery(":text[name='order_zip01']").val();
var order_zip02 = jQuery(":text[name='order_zip02']").val();
var order_zip = '〒' + order_zip01 + '-' + order_zip02;
// 都道府県
var order_pref = jQuery("select[name='order_pref'] :selected").text();
// 住所
var order_addr01 = jQuery(":text[name='order_addr01']").val();
var order_addr02 = jQuery(":text[name='order_addr02']").val();
var order_addr = order_addr01 + order_addr02;
var order_zip_pref_addr = order_zip + order_pref + order_addr;
// TEL
var order_tel01 = jQuery(":text[name='order_tel01']").val();
var order_tel02 = jQuery(":text[name='order_tel02']").val();
var order_tel03 = jQuery(":text[name='order_tel03']").val();
var order_tel = '℡' + order_tel01 + '-' + order_tel02 + '-' + order_tel03;

// お名前
var order_name01 = jQuery(":text[name='order_name01']").val();
var order_name02 = jQuery(":text[name='order_name02']").val();
// フリガナ
var order_kana01 = jQuery(":text[name='order_kana01']").val();
var order_kana02 = jQuery(":text[name='order_kana02']").val();
var order_name_kana = order_name01 + order_name02 + ' ' + order_kana01 + order_kana02;

// お届け先の数だけ繰り返す
var i = 0;
jQuery("#[id*='shipping_id_']").each(function (index, value) {
    /*
     * お届け先情報
     */
    // 郵便番号
    var shipping_zip01 = jQuery(":text[name='shipping_zip01[" + i + "]']").val();
    var shipping_zip02 = jQuery(":text[name='shipping_zip02[" + i + "]']").val();
    var shipping_zip = '〒' + shipping_zip01 + '-' + shipping_zip02;
    // 都道府県
    var shipping_pref = jQuery("select[name='shipping_pref[" + i + "]'] :selected").text();
    // 住所
    var shipping_addr01 = jQuery(":text[name='shipping_addr01[" + i + "]']").val();
    var shipping_addr02 = jQuery(":text[name='shipping_addr02[" + i + "]']").val();
    var shipping_addr = shipping_addr01 + shipping_addr02;
    var shipping_zip_pref_addr = shipping_zip + shipping_pref + shipping_addr;
    // TEL
    var shipping_tel01 = jQuery(":text[name='shipping_tel01[" + i + "]']").val();
    var shipping_tel02 = jQuery(":text[name='shipping_tel02[" + i + "]']").val();
    var shipping_tel03 = jQuery(":text[name='shipping_tel03[" + i + "]']").val();
    var shipping_tel = '℡' + shipping_tel01 + '-' + shipping_tel02 + '-' + shipping_tel03;

    // お名前
    var shipping_name01 = jQuery(":text[name='shipping_name01[" + i + "]']").val();
    var shipping_name02 = jQuery(":text[name='shipping_name02[" + i + "]']").val();
    // フリガナ
    var shipping_kana01 = jQuery(":text[name='shipping_kana01[" + i + "]']").val();
    var shipping_kana02 = jQuery(":text[name='shipping_kana02[" + i + "]']").val();
    var shipping_name_kana = shipping_name01 + shipping_name02 + ' ' + shipping_kana01 + shipping_kana02;

    // お届け時間
    var time_id = jQuery("select[name='time_id[" + i + "]'] :selected").text();
    // お届け日
    var shipping_date_year = jQuery("select[name='shipping_date_year[" + i + "]'] :selected").text();
    var shipping_date_month = jQuery("select[name='shipping_date_month[" + i + "]'] :selected").text();
    var shipping_date_day = jQuery("select[name='shipping_date_day[" + i + "]'] :selected").text();
    var shipping_date = shipping_date_year + '年' + shipping_date_month + '月' + shipping_date_day + '日';

    // データ格納
    arr.push(i + '\t' + shipping_zip_pref_addr + ' ' + shipping_tel + '\t' + shipping_name_kana + '\t' + order_zip_pref_addr + ' ' + order_tel + '\t' + order_name_kana + '\t' + shipping_date + ' ' + time_id);
    i++;
});

// 表示データ用変数
var show = '';
$.each(arr, function (index, value) {
     show = show + value + "\n";
});
console.log(show);

ポイント1.JavaScript でスクレイピングする

Chrome のデベロッパーツールなどの開発ツールを使い、jQuery のセレクタで必要な要素を取得して繰り返し処理を行います。

個々のくり返しの中で、要素から文字列を取り出し、前後の空白を除去して配列に追加していきます。

最後に、配列の内容を出力、という流れでございます。

ほしい要素を調べるには、Chrome でウェブページを表示してほしい要素を選択して右クリック「要素の検証」で起動するウェブマスターツールで表示されますわ♪

上述しました貼り付ける JavaScript ソースの大枠の流れも同じですの。次のプログラムが長くなっただけですわ♪

var arr = [];
jQuery("table.form td").each(function (index, value) {
     var val = $.trim($(this).text());
     arr.push(val);
});

$.each(arr, function (index, value) {
     console.log(value + "\n");
});
arr = [];

これは、次のページの方法を使わせていただきました。ありがとう存じます!

また、JavaScript での配列の使い方について、次のページでより詳しく知ることができました。感謝いたします!

ポイント2.お届け先の件数を取得する

id 属性に「shipping_id_」を含む id 要素を選択して繰り返すように、jQuery のセレクタを使用いたしました。

id 属性に「shipping_id_」を含む id 要素とは例えば、<input type=”hidden” name=”shipping_id[1]” value=”1″ id=”shipping_id_1″> ですわ。この要素以外に id=”shipping_id_2″ なども選択したいですの。

jQuery セレクタで id を指定する場合は jQuery(“#id”) などといたしますわね。でもこれでは選択できる要素は1つだけです><。わたくしは、もっともっと、あるだけ取得したいのですの。

つまり jQuery セレクタで id を検索したいのに、# の後には検索対象の id 文字列を入れることができません><。

そこで属性フィルタの [] を使用して、フィルタに引っかかった id 属性を持つ要素を全て選択できるようにいたしました。

フィルタの前に # を付けております。id という文字列ではダメでした。試行錯誤して最初に選択できた書き方を採用いたしました。

var i = 0;
jQuery("#[id*='shipping_id_']").each(function (index, value) {
    console.log(i);
    i++;
});

特に参考ページはございませんけれども、次以降のボツも含めたポイントから、自身で導き出しました。

ポイント3.フォームの入力欄に記入された値を取得する

つまり、input の value 値がほしいのですの♪

input をセレクトで取得して、val 関数をつなげるだけですわ♪

console.log(jQuery(":text[name='order_name01']").val());

こちらのページが参考になりました。ありがとう存じます!

ポイント4.セレクトボックスで選択された選択肢のラベル(表示された文字列)を修得する

セレクタで :select を書き、text 関数をつなげることがポイントですの!

console.log(jQuery("select[name='order_pref'] :selected").text());

以下、結局使わなかった調査結果ですけれども、引き続きポイントを書いていきますの♪

これには大変助けていただいたページがございます。ありがとう存じます!

ポイント5.「:first」先頭の要素を選択、「:gt(n)」n番目より後の要素を選択、を同時に行う。結局未使用ですけれども。

結局使わなくてボツになったのですけれども、、、メモいたします。

id が order-edit-products である最初の要素を選択したい、その要素内の tr で2つ目以降の要素を選択したい、以上のことが希望でした。

id が同じ要素が2つ以上あったのですけれども、それは置いておいて。。。

id が order-edit-products である最初の要素を選択するには #order-edit-products:first といたします。

そして、tr で2つ目以降の要素を選択するには tr:gt(0) といたします。

:gt(0) は2つ目以降を指定する、という意味になります。要素の添字は 0 から始まります、つまり1番目の要素を意味します。そして gt は greater than の略なのでしょう、〜よりも大きい、を意味します。

合わせますと1番目よりも大きい要素、つまり2番目以降、となります。ちょっと難しいですわね♪

var arr = [];
jQuery("#order-edit-products:first tr:gt(0)").each(function (index, value) {
    // 要素のテキストを取得
    var val = $.trim($(this).text());
    arr.push(val);
});

$.each(arr, function (index, value) {
    console.log(value + "\n");
});
arr = [];

次のページが参考になりました。ありがとう存じます!

ポイント6.JavaScript で文字列を含むかを判定する方法。これもボツですけれども

セレクタに text 関数をつなげるなどして得た文字列に、指定した文字列が含まれれているかどうかを判定する方法です。

テキストに match 関数をつなげ、関数内で /文字列/ で含むかどうか判定したい文字列を指定いたします。

例えば「小計」が含まれているかどうか判定するには、if($(this).text().match(/小計/)) となります。

var arr = [];
jQuery("#order-edit-products:first tr:gt(0)").each(function (index, value) {
    // 商品情報の行に辿り着いたら以降は破棄
    if($(this).text().match(/小計/)) { return false; }
    // 要素のテキストを取得
    var val = $.trim($(this).text());
    arr.push(val);
});

このページが参考になりました。ありがとう存じます!

ポイント7.jQuery の each 関数で、途中で次の要素に行く continue、途中でくり返しを抜ける break。これもボツです

  • 途中で次の要素に行く continue → return true;
  • 途中でくり返しを抜ける break → return false;

とします。ポイント6では、return true; で continue しております。

使うことはありませんでしたが、次のページが参考になりました♪感謝いたします!

ポイント8.セレクタで親要素を選択する。これも未使用ですの

セレクタの後に parent 関数をつなげるだけですわ。セレクタ内で子要素は指定いたしますので、親も同様に指定できるのかと勘違いしてしばらく探してしまいましたの><。違いましたわ、てへ。

// product_name[0] の親の td を取得
var arr = [];
jQuery("#order-edit-products :hidden[name*='product_name']").parent().each(function (index, value) {
    // テキストを取得し、「変更」「削除」空白削除し、配列に追加
     var val = $(this).text().replace("変更","");
     val = val.replace("削除","");
     val = $.trim(val);
     arr.push(val);
});
$.each(arr, function (index, value) {
     console.log(value + "\n");
});
arr = [];

次のページが参考になりました。ありがとう存じます!

ポイント9.文字列から、指定した文字列を削除する方法。これもやはり未使用です

削除用の関数は見あたりませんでしたの。ですので replace 関数を使用して置き換え後の文字列として空文字を指定するようにいたしました。

ポイント8で使用しておりますの。次のページを参考にさせていただきました。感謝いたします!

おわりに

ボツになりましたけれども、次のページが今回の調査を進めてみようと思わせてくださった投稿ですの。CakePHP についても造詣が深い方ですわね。ありがとう存じます。

振り返ってみますと今回の投稿、没となった調査項目が多いですわね、えへへ。

ほとんどすべて忘れてしまうのでしょうけれども、またこの投稿を見れば調べる手間が省けますので、トータルでは前進!、、、、、、と思います♪

本投稿のプログラム、長い間は使えないと思います。EC-CUBE のバージョンアップや、カスタマイズで変わっていくことと思います。

ですので自分自身でメンテナンスしながら、取得できるように合わせて行ったり、出力するフォーマットを変えたりできるようにすることが大事と存じます。

ですのでボツネタも残しましたの♪

以上です。

コメントを残す