Pythonスクレイピングでメルカリの売り上げ情報を自動収集する方法

Pythonスクレイピングでメルカリの売り上げ情報を自動収集する方法
えびかずき
えびかずき

こんにちは、えびかずきです。

今回はPythonでメルカリのWebページをスクレイピングしていきたいと思います。

こんな人におすすめ:

・メルカリの売り上げ情報を自動で収集したい。
・PythonでSeleniumを使ってスクレイピングをしてみたい。

こんな人にはおすすめでない:
・Beautiful Soupでスクレイピングをしたい。

結論として、SeleniumのWebdriver機能でChromeを操作して、メルカリのマイページの情報を自動で収集できます。

Advertisement

開発環境

・MacOS Catalina10.15.7

・Python 3.8.2

・selenium 3.141.0
・pandas 1.2.0

ライブラリはpipで以下のようにインストールできます。

% pip install selenium==3.141.0
% pip install pandas==1.2.0 

やりたいこと

メルカリには売り上げ情報や購入情報をcsvでまとめて出力するような機能がないので、スクレイピングで自作できないか?

やりたいこと:
マイページの出品した商品ページの項目(下図)に表示されている売却済み商品の情報を全て抜き出して、csvファイルへ書き込む。

抜き出す情報:
・商品ID
・商品名
・価格
・送料負担
・販売手数料
・送料
・販売利益
・販売日時

手順①:ChromeDriverのダウンロード

http://chromedriver.chromium.org/downloadsからChromeDriverをダウンロードして、手順②で作成する.pyと同じディレクトリに保存します。

複数のダウンロードファイルが準備されていますが、自分のChromeバージョンとOSに適合するものを選択してください。

お使いのChromeバージョンはchrome://version/から確認できます。

私の場合は、ChromeDriver 87.0.4280.88のchromedriver_mac64.zipを使っています。

手順②:Pythonコードの作成

1.SeleniumでChromeを起動する

2.出品した商品ページから商品IDを取得する関数[item_id_get()]を作成する

3.商品IDの販売情報ページにアクセスして情報を抜き出す関数[info_get()]を作成する

4.item_id_get()で商品IDを取得し、その商品IDを元にinfo_get()で販売情報を取得して、その結果をcsvに書き込む、main関数を作成する。

5.main関数を実行して、スクレイピング完了。

ソースコード

ソースコードは以下の通り。

profile_pathのところを自分のパスに変更して使ってください。

#メルカリ収益自動取得プログラム

import pandas as pd
from selenium import webdriver
import time
import csv
import os

#Pandas.dfの準備
columns = ["商品ID","商品名", "価格", "送料負担","販売手数料", "送料","販売利益","販売日時"]

#chromeの起動
options = webdriver.chrome.options.Options()
profile_path = '/Users/sogakazuki/Library/ApplicationSupport/Google/Chrome/selenium'
options.add_argument('--user-data-dir=' + profile_path)
browser = webdriver.Chrome("./chromedriver", options=options)
time.sleep(5)    #起動時に時間がかかるため、5秒スリープ

# 出品した商品ページから商品IDを取得する関数
def item_id_get(url):
    item_id = []
    try:
        while(True):
    
            browser.get(url)
            posts = browser.find_elements_by_css_selector(".js-mypage-item")
   
            for post in posts:
                # 商品IDの取得
                item_id.append(post.get_attribute("data-item-id"))
        
            next_url = browser.find_element_by_css_selector(
                    "li.pager-next.pager-cell a").get_attribute("href")
            if next_url != url:
                url = next_url
            else:
                break
    except:
        print("item_id_getは中断されました。")
        import traceback
        traceback.print_exc()
    
    return item_id


# 商品IDから販売情報を取得する関数
def info_get(item_id):
    browser.get("https://www.mercari.com/jp/transaction/order_status/" + item_id + "/")
    posts = browser.find_elements_by_css_selector(".transact-info-table-cell")
    raw_info = []
    for post in posts:
        raw_info.append(post.text)
        # df向けに整形
    
    name_price = raw_info[1].split("\n")
    info = pd.Series([item_id,name_price[0], name_price[1], raw_info[3], raw_info[5], 
                        raw_info[7], raw_info[9], raw_info[11]], columns)        
    return info

#main関数
def main():
    
    df = pd.DataFrame(columns=columns)
    
    #売却済みの全商品IDをリストで取得する
    url = "https://www.mercari.com/jp/mypage/listings/completed/"
    item_id_list  = item_id_get(url)

    #商品IDごとに販売情報を取得してdfに追加
    index = 0
    index_max = len(item_id_list)
    try:
        while(True):
            info = info_get(item_id_list[index])
            df = df.append(info,columns)
            index += 1
            if index >= index_max:
                break
            time.sleep(2)    #大量リクエストの防止で2秒止める
    except:
        print("info_getは中断されました。")
        import traceback
        traceback.print_exc()
     
    #csvを保存する
    filename = "メルカリ販売リスト" + ".csv"
    df.to_csv(filename, encoding="utf-8-sig")
    
    #chromeを閉じる
    browser.quit()
    
    return print("Finish!")
        

main()

ポイント:

ログイン情報を保持するために

・メルカリへのログイン状態を保持するために、Chromeのユーザー情報を設定してからWebdriverを動かす必要があります。

ユーザー情報は、chrome://version/にアクセスすることで閲覧できます。
プログラムで使う情報は、このうちのプロフィール パスです。

/Users/username/Library/Application Support/Google/Chrome/Default

ただし、メインで使用しているプロフィールパスを使うと、手動で使っている方と干渉して以下のようなエラーが発生することがあるので、Selenium用に新しいプロフィール パスを作成して運用することをお勧めします。

InvalidArgumentException: Message: 
invalid argument: user data directory is already in use, please specify a unique value for --user-data-dir argument, or don't use --user-data-dir

新しいプロフィールパスは単純に、/Users/username/Library/Application Support/Google/Chrome/のディレクトリに何らかの名前を付けた空のフォルダを作ればいいだけです。

ちなみに1回目のプログラム実行時は、メルカリのログインページが開くので、必要な情報を入力してログインする必要があります。

2回目からはログイン不要になります。

商品IDは複数の「出品した商品ページ」から取得する必要がある

全ての商品IDを取得するには、下図のように次ページへ進むボタンからどんどん過去に遡っていく必要があります。

一つのページで商品IDの取得が終われば、次のページに進んで同じことをやるようにプログラムを作ります。(ソースコード参照)

商品情報はHTMLの「.transact-info-table-cell」要素から取り出す

下図赤枠の商品情報はHTMLの「.transact-info-table-cell」要素から取り出せます。

情報の取り出しには、Seleniumの「.find_elements_by_css_selector」メソッドを使います。(ソースコード参照)

サイトに記載されている情報がどのHTML要素に対応しているかは、「F12」でディベロッパーツールを開いて「Elements」タブから確認することができます。

取得データはPandasのDataFrameでまとめてからcsv化

取得した商品データはPandasのDataFrameでまとめてからcsv化するとやりやすいです。

DataFrameのcsv化は、DataFrame.to_csv()を使います。

Advertisement

まとめ

今回はPythonでSeleniumを使ってメルカリの売り上げ情報を自動収集してみました。

ソースコードは少し長めですが、スクレイピングのやり方自体はかなり単純で、SeleniumでChromeを起動して、特定のWebページからHTML情報を抜き出すという、ただそれだけです。

私自身メルカリのヘビーユーザーなので、今回のプログラムがかなり役に立ちました。

手作業で一つ一つ情報を確認していたら日が暮れてしまいますからねえ。。

Seleniumでは、今回紹介したHTML情報の抜き出し以外にも、クリック操作の自動化なども出来ますので、色々試して遊んでみると楽しいですよ。

Webスクレイピングはココナラやクラウドワークスなどの副業案件でも割と多くみかけますので、世間的に需要は高い技術です。

Pythonだと意外と簡単に実装できますので、ぜひトライしてみでください!

参考URL

コードを作成するにあたって、以下の記事が参考になりました。

メルカリを python スクレイピングして出品した商品をバンバン売りたい

Seleniumで次の実行時にもサイトのログイン状態を維持したい場合

参考書籍

Python/selenium環境でWebスクレイピング方法が、初心者にもわかりやすく紹介されています。

プログラム作成の参考になりました。

おまけ:購入した商品の自動集計プログラム

同様にして、購入した商品の自動集計プログラムも実装してみました。

マイページの購入した商品のページから商品情報を取得して、csv形式で出力します

ソースコードは以下の通り。

profile_pathのところを自分のパスに変更して使ってください。

#メルカリ購入データ自動取得

import pandas as pd
from selenium import webdriver
import matplotlib.pyplot as plt
import time
import csv
import os

#Pandas.dfの準備
columns = ["商品名", "価格",  "送料負担","販売日時"]

#chromeの起動
options = webdriver.chrome.options.Options()
profile_path = '/Users/username/Library/ApplicationSupport/Google/Chrome/selenium'
options.add_argument('--user-data-dir=' + profile_path)
browser = webdriver.Chrome("./chromedriver", options=options)
time.sleep(5)    #起動時に時間がかかるため、5秒スリープ

#main関数
def main():
    
    df = pd.DataFrame(columns=columns)
    
    #購入済みの全商品urlをリストで取得する
    url = "https://www.mercari.com/jp/mypage/purchased/"
    item_url_list  = item_url_get(url)

    #商品IDごとに販売情報を取得してdfに追加
    index = 0
    index_max = len(item_url_list)
    try:
        while(True):
            info = info_get(item_url_list[index])
            df = df.append(info,columns)
            index += 1
            if index >= index_max:
                break
            time.sleep(2)    #大量リクエストの防止で2秒止める
    except:
        print("info_getは中断されました。")
        import traceback
        traceback.print_exc()
     
    #csvを保存する
    filename = "メルカリ購入リスト" + ".csv"
    df.to_csv(filename, encoding="utf-8-sig")
    
    #chromeを閉じる
    browser.quit()
    
    return print("Finish!")
        
# 出品した商品ページから商品URLを取得する関数
def item_url_get(url):
    item_url = []
    page = 1
    posts =[0]
    try:
        while(len(posts)>0):
    
            browser.get(url)
            posts = browser.find_elements_by_css_selector("a.mypage-item-link")
   
            for post in posts:
                # 商品URLの取得
                item_url.append(post.get_attribute("href"))
                
                
            page += 1
            next_page = "https://www.mercari.com/jp/mypage/purchased/?page="+ str(page)
            url = next_page 
            
    except:
        print("item_url_getは中断されました。")
        import traceback
        traceback.print_exc()
    
    return item_url

# 商品IDから販売情報を取得する関数
def info_get(item_url):
    browser.get(item_url)
    posts = browser.find_elements_by_css_selector(".transact-info-table-cell")
    raw_info = []
    for post in posts:
        raw_info.append(post.text)
        # df向けに整形
    
    name_price = raw_info[1].split("\n")
    info = pd.Series([name_price[0], name_price[1], raw_info[3], raw_info[5]], columns)        
    return info

main()

Pythonカテゴリの最新記事