プログラミングを少し使って今流行りの電脳せどり物販のリサーチを半自動化してみた

###はじめに
クラウドファンディングのCAMPFIREでエンジニアをしている堤です。
今回は2021年のアドベントカレンダー用の記事になります。
![christmas-g0d2446883_1280.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/344229/c8b17f07-29b2-185b-e243-6c9241ae9f27.jpeg)
昨年は[プログラミングを少し使ってFXの検証を自動化してみた](https://qiita.com/tatsuya223/items/822ffc1e5fde49f9b958)という記事でしたが、
今年は同じく少しプログラミングを使って自動化してみたシリーズとして
<b>「今流行りの電脳せどり物販のリサーチを半自動化してみた」</b>という内容です。

せどり物販はコロナの影響もあり参入者が急増し、
今最もポピュラーな副業の一つとしてもよく取り上げられているので
ご存知の方も多いかと思います。

せどり物販のことを簡単に説明すると、
<b>「商品を安く買って高く売り、差益を得る」</b>ビジネスのことです。
（「電脳」というのは、仕入れを実店舗ではなく、オンラインで行うことです）

例えば古本屋で10円で販売されている本を買って、Amazonで500円で販売するなどです。

私の友人や知人にも、副業ではなく法人の事業としてですが、
アンティークコインや自動車などを商材に取り組んでいる人や
メーカーから直接仕入れた商品を問屋に販売するなど、
商社のような立場で取り組んでいる人などもいます。
（もはや、せどりと言えるかわからないですが・・）

前置きが長くなりましたが、今回はプログラミングを少し使って
せどり物販のリサーチ作業を半自動化する方法をざっくりとご紹介します！

***

###リサーチを半自動化する方法
今回はリサーチを半自動化するために、スクレイピングを行います。
（スクレイピングとは、ウェブサイトから指定した情報を抽出、加工することをいいます）

スクレイピングの手法はいくつかあるのですが、
今回はポピュラーで手軽な<b>Google Apps Script（GAS）</b>でのでのスクレイピングを行います。

GASでスクレイピングを行う主なメリットは以下の通りです。

・環境開発の必要がないため、多少のプログラミングの知識があればできる。
・抽出したデータをGoogleスプレッドシートに出力できる。


[補足]
今回はあくまでもリサーチ自動化の部分がメインの内容のため、
GASの初期設定に関する記事は既にたくさん優良な記事がありますので、そちらをご参照ください。

[注意]
実践する際は、対象サイトがスクレイピングを許諾しているか否かの確認が必要です。
今回はあくまでもお試しになります。

***
###リサーチの対象と手順
####【対象】
AmazonとauPAYマーケット(Wowma)での同一商品の価格比較

####【手順】
(1) AmazonとauPAYマーケット(Wowma)で仕入れ予定の商品詳細ページのURLをリスト化する
(2) URLから指定の情報（商品名、価格など）をスプレッドシートに抽出するGASを作成
(3) GASを実行し、売値が安いサイトで商品を買い、高いサイトで販売して差益を得る

※各サイトでの商品価格は日々変化するので、商材リストの価格比較を定期的に実行する前提です。
※一方のサイトの商品からもう一方のサイトの同一商品を引っ張る予定でしたが、同一商品が複数店舗や複数カタログでの出品されているケースも多かったため、URLリスト作成は手動になります。

[前提条件]
前提条件としてAmazon、auPAYマーケット(Wowma)での販売体制があること、
メーカーや各販売プラットフォームでの販売許可があることなどがあります。

また実際には各サイトでのポイントや手数料、送料なども考慮する必要がありますが、
今回はスクレイピングを試してみることが目的なので、その辺りは置いておきます。

***
###具体的なGASのコード（※商品は試しに3件のみです）
####Amazon情報取得用のGAS(キャプチャ)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/344229/6e6200f1-58c4-23e3-4062-08d9141a7b46.png)

```javascript:Amazon情報取得用GAS(コード)
function getInfoAmazon(){
 //取得するURLを設定（複数可能）
 const url = [
  'https://www.amazon.co.jp/dp/B08MZPFCSB',
  'https://www.amazon.co.jp/dp/B078JYN4G3',
  'https://www.amazon.co.jp/dp/B01MUBY004'
 ];

 //データを出力するスプレッドシートのIDを指定（※手元のスプレッドシートのURLにあるIDに置き換える）
 const spreadsheet = SpreadsheetApp.openById("1rZuKZL9JOoLQZTm-dwV59bkiHm4NlR3C8DT05gJX8Bk")

 //データを出力するスプレッドシートのシート名を指定（※手元のスプレッドシートの出力用シートのタブ名）
 const sheet = spreadsheet.getSheetByName('Amazon')

 //スプレッドシートの最後の行に追記する設定
 let lastrow = sheet.getLastRow();
 let targetrow = lastrow + 1;

 for (let i = 0 ;i < url.length;i++){
    let contents = UrlFetchApp.fetch(url[i]).getContentText("UTF-8");

    let $ = Cheerio.load(contents,{
      decodeEntities: false
    });

    //タイトル取得
    let title = $("#titleSection > #title").text();
    
    //価格取得
    let price = $(".a-offscreen").first().text();
    
    //取得した情報をスプレッドシートに追加
    sheet.getRange("A" + targetrow).setValue(title);
    sheet.getRange("B" + targetrow).setValue(price);

    //次の行に移動
    targetrow++

    //繰り返し処理にインターバルを設定
    Utilities.sleep(5000);
 } 
}
```
####auPAYマーケット(Wowma)情報取得用のGAS(キャプチャ)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/344229/45d97a97-c031-b4b2-581b-2787b55e808b.png)

```javascript:auPAYマーケット(Wowma)情報取得用GAS(コード)
function getInfoWowma(){
 //取得するURLを設定（複数可能）
 const url = [
  'https://wowma.jp/item/483490813',
  'https://wowma.jp/item/330753917',
  'https://wowma.jp/item/375154565'
 ];

 //データを出力するスプレッドシートのIDを指定（※手元のスプレッドシートのURLにあるIDに置き換える）
 const spreadsheet = SpreadsheetApp.openById("1rZuKZL9JOoLQZTm-dwV59bkiHm4NlR3C8DT05gJX8Bk")

 //データを出力するスプレッドシートのシート名を指定（※手元のスプレッドシートの出力用シートのタブ名）
 const sheet = spreadsheet.getSheetByName('Wowma')

 //スプレッドシートの最後の行に追記する設定
 let lastrow = sheet.getLastRow();
 let targetrow = lastrow + 1;

 for (let i = 0 ;i < url.length;i++){
    let contents = UrlFetchApp.fetch(url[i]).getContentText("Shift_JIS");

    let $ = Cheerio.load(contents,{
      decodeEntities: false
    });

    //タイトル取得
    let title = $(".pb20 > h1").first().text();
    
    //価格取得
    let price = $(".priceValue > #js-baseItemPrice").first().html();

    //ストア名取得
    let store = $(".shopLink > .stIconMd-store").first().text();

    //JANコード入りURL取得（※JANコードとは、国内のあらゆる商品についている商品識別番号のようなものです）
    let jan = $("link[rel='canonical']").attr('href');

    //取得した情報をスプレッドシートに追加
    sheet.getRange("A" + targetrow).setValue(title);
    sheet.getRange("B" + targetrow).setValue(price);
    sheet.getRange("C" + targetrow).setValue(store);
    sheet.getRange("D" + targetrow).setValue(jan);

    //次の行に移動
    targetrow++

    //繰り返し処理にインターバルを設定
    Utilities.sleep(5000);
 } 
}
```
***
###GASの実行結果
####Amazon情報取得内容
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/344229/e5ebf1d6-d3d3-930e-afa9-c48e0f517001.png)

####auPAYマーケット(Wowma)情報取得内容
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/344229/d71ac1fa-33fb-4124-239d-2f8b140d6473.png)

####AmazonとauPAYマーケット(Wowma)情報を統合したシート
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/344229/4db08a39-6baf-4342-252b-a70c18d645aa.png)
※M列の価格差が大きい商品が、安く買える方の店舗で仕入れ対象になる可能性が高いということになります

***
###終わりに
今回プログラミングを使う要素はそう多くはありませんが、
少しのコードを書くだけで大幅なリサーチ時間の短縮をすることができます。

商品リストが数件であれば手動でいいですが、数百件などあった場合、
各商品の情報を手動で一つずつ各サイトで確認していくのはあまりに効率が悪いです。

実は自分も今回の記事を書くまでちゃんとGASを使用したことがなかったのですが、
思っていた以上に簡単に作業効率を高めることができ、今後活用していこうと思いました。

この記事が読んでくださった方のお役に少しでも立てれば幸いです。
最後まで読んでくださってありがとうございました！