メルカリのスクレイピングをわかりやすく解説【カテゴリーIDの抽出】

メルカリのスクレイピングをわかりやすく解説【カテゴリーIDの抽出】 プログラミング

メルカリをスクレイピングしていきます。
最初は、カテゴリー一覧ページからスクレイピングします。

なぜ、カテゴリー一覧ページからスクレイピングすると思いますか?
その回答は、後ほど説明します。

本記事の内容

  • スクレイピングの種類
  • 大量データのスクレイピング方法
  • カテゴリー一覧ページのスクレイピング
  • メルカリの珍しいスクレイピング対策

それでは、上記に沿って解説していきます。

スクレイピングの種類

スクレイピングには、大きく分けて二つの種類があります。

  • 大量データの抜き出し
  • 指定ページの監視

大量データとは、その言葉通りに多くのデータのことです。
場合によっては、全データということもあるでしょう。

また、指定した分類のみのデータということもあります。
分類の例としては、以下のようなモノがあります。

  • カテゴリー
  • キーワード

上記の大量データの抜き出しは、イメージしやすいでしょうね。
もう一つの指定ページの監視は、あまり認知されていないかもしれません。

例えば、ある商品の在庫をチェックするなどで使う手段です。
実際、私はSwitchが手に入りにくいときにその手をつかいました。

販売ページにおいて在庫があるなら、「〇」が表示される仕様だったはずです。
「〇」を認識したら、自動でLineに通知するようにしていました。
当時は、その仕組みによりSwitchを手に入れることができました。

スクレイピングには、そのような使い方もあるという良い例ですね。

今回は、大量データの抜き出しのパターンとなります。
このパターンを説明していきます。

大量データのスクレイピング方法

大量データを取得するためには、各データ(メルカリなら商品)のURLを知る必要があります。
正直、このデータのURLリストを用意することがスクレイピングの肝となります。

ここは、設計能力が問われる部分と言っても過言ではありません。
つまり、対象サイトのデータの持ち方(データ構造)を理解する必要があるのです。

このことをターゲットとなるメルカリで確認していきましょう。

まず、スクレイピングする際、カテゴリー一覧からデータを抽出していきます。
カテゴリー一覧をスクレイピングすれば、カテゴリーIDを取得できます。

メルカリにもカテゴリー一覧ページが存在します。
https://www.mercari.com/jp/category/

現時点では、以下が大カテゴリーとして扱われています。
大カテゴリーの数は、全部で13個ですね。

大カテゴリーの下には、多くのカテゴリーが紐づいています。
しかし、大カテゴリーのIDを取得できれば、それでOKです。

次に、カテゴリーIDからそのカテゴリーに紐づく商品一覧ページのURLを作成できます。
そして、商品一覧ページをスクレイピングすれば、商品IDを取得できます。

さらに、商品IDからその商品詳細ページのURLが作成可能です。
このようにドリルダウンしていくことで、最小単位となる商品までたどり着けます。

結果として、商品ページのURLリストを作成できます。
このURLリストがあれば、あとはそれをバッチ処理で対応していくだけです。

では、メルカリのカテゴリーページをスクレイピングしてみましょう。

カテゴリー一覧ページのスクレイピング

これから実際に動くプログラムを載せていきます。
各自でそのプログラムを動かす場合は、次の記事で準備をしてください。

そして、絶対に【必須】は読んでください。
そうしないと、大変なことになりかねません。

準備が整ったら、次のコードを動かしていきましょう。
サンプルコードとして、現時点(2021年2月4日)で動くコードを載せています。

サンプルコード

import bs4
import traceback
from selenium import webdriver
from selenium.webdriver.chrome.options import Options

# ドライバーのフルパス
CHROMEDRIVER = "chromedriver.exeのパス"


# ドライバー準備
def get_driver():
    # ヘッドレスモードでブラウザを起動
    options = Options()
    options.add_argument('--headless')

    # ブラウザーを起動
    driver = webdriver.Chrome(CHROMEDRIVER, options=options)

    return driver


# 対象ページのソース取得
def get_source_from_page(driver, page):
    try:
        # ターゲット
        driver.get(page)
        driver.implicitly_wait(10)  # 見つからないときは、10秒まで待つ
        page_source = driver.page_source

        return page_source

    except Exception as e:

        print("Exception\n" + traceback.format_exc())

        return None


# ソースからスクレイピングする
def get_data_from_source(src):
    # スクレイピングする
    soup = bs4.BeautifulSoup(src, features='lxml')
    #print(soup)
    try:
        info = []
        # 大カテゴリー毎に要素を取得
        elems = soup.find_all(attrs={"data-test": "category-list-individual-box"})

        for elem in elems:
            # 最初に出てくるaタグ(「すべて」)の要素を取得
            a_tag = elem.find("a")

            if a_tag:
                href = a_tag.attrs['href']
                category_id = href.replace("/jp/category/", "")
                info.append(category_id)

        return info

    except Exception as e:

        print("Exception\n" + traceback.format_exc())

        return None


if __name__ == "__main__":
    # 対象ページURL
    page = "https://www.mercari.com/jp/category/"

    # ブラウザのdriver取得
    driver = get_driver()

    # ページのソース取得
    source = get_source_from_page(driver, page)

    # ソースからデータ抽出
    data = get_data_from_source(source)

    # 閉じる
    driver.quit()

    # 結果表示
    print(data)

上記を実行すると、次の結果が表示されます。
大カテゴリーのIDです。

['1', '2', '3', '4', '5', '1328', '6', '7', '8', '9', '1027', '1318', '10']

全部で13個あるので、上手くスクレイピングできています。
正直、13個程度ならスクレイピングまでする必要はありませんけどね。

プログラムの内容は、細かくは説明しません。
「大量データのスクレイピング方法」をベースにプログラミングしています。
それに、コメントを見れば大体は理解できるはずです。

以下だけ説明しておきましょう。

# ドライバーのフルパス
CHROMEDRIVER = "chromedriver.exeのパス"

これは、それぞれの環境で異なるでしょう。
各自で値を変更してください。

以上で終わってもいいのですが、最後にメルカリのスクレイピング対策について説明しておきます。

メルカリの珍しいスクレイピング対策

「カテゴリー一覧ページのスクレイピング」では、サクッとスクレイピングしています。
しかし、少しだけ苦労しました。

それは、メルカリのサイトがスクレイピング対策をしているからです。
それも地味に嫌な対策をしてきます。

私は、過去に多くのサイトをスクレイピングしてきました。
しかし、メルカリの対策は初めてのケースかもしれません。

その対策とは、タグ要素のclass名をセッション毎に変更するのです。

例えば、カテゴリー一覧には次ようなタグが存在しています。
「name=”category-1″」で検索すれば、ヒットします。

<div name="category-1" data-test="category-list-individual-box" class="sc-kvkilB ducAME">

ただし、「class=”sc-kvkilB ducAME”」部分は異なる値のはずです。
このようなclass名の値が、セッション毎に異なってきます。

だから、class名を使って要素を抽出できないのです。
スクレイピングをやる上で、これは地味にダメージを受けます。

しかし、データ属性に関してはセッション毎に変更することはありません。
上記の例でいえば、「data-test=”category-list-individual-box”」の部分です。

そのため、メルカリではclass名ではなくデータ属性でスクレイピングをしていきます。

次回は、商品一覧画面のスクレイピングを行う予定です。
その際にも、この考え方で対応できるのかどうかということですね。

やっぱり、スクレイピングは面白いです。
各サイトのエンジニアとの知恵比べが、単純にワクワクします。

タイトルとURLをコピーしました