Pythonでやる奴

Python出来る→機械学習も出来る→価値UPで年収UPでやりがいUP→いつかは田舎暮らししたい男のブログ

メルカリをスクレイピングして商品リンク、画像、価格を取得する

タイトルの通り!

要素の取得方法など勉強がてら、みんな大好きスクレイピングを実装しました。 ここまで出来ればcsvに吐き出すことは余裕のよっちゃんよね。


from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.ui import Select
# 件数表示用
count = 0


def main():
    # chromeDriverの位置
    driver = webdriver.Chrome('/usr/local/bin/chromeDriver')

    set_search_conditions(driver)
    get_item(driver)

    driver.close()


def set_search_conditions(driver):
    driver.get('https://www.mercari.com/jp/')
    # 検索窓の要素を取得
    s = driver.find_elements_by_name('keyword')
    """
    レスポンシブ対応のためkeyword要素が2つある。(スマホ、PC)
    ここでは、PCサイトを前提とするため、2つ目の要素を使用する。
    """
    # 検索キーワードを入力
    s[1].send_keys('iPhoneX')
    # Enterキーを入力する
    s[1].send_keys(Keys.ENTER)

    # 詳細条件を設定
    """ カテゴリ
    1 : レディース
    2 : メンズ
    ...
    7 : 家電・スマホ・カメラ
    """
    # 親カテゴリ
    # Selectクラスを使うと容易にプルダウンメニューを選択できる。
    category_root = Select(driver.find_element_by_name('category_root'))
    category_root.select_by_visible_text('家電・スマホ・カメラ')
    # value値でも指定可能
    # category_root.select_by_value('7')

    # 子カテゴリ
    category_child = driver.find_element_by_xpath(
        '/html/body/div[1]/main/div[2]/form/div[2]/div[2]/div[2]/div[8]/select/option[2]')
    category_child.click()
    """ 下記の入力方法も出来るかと思ったが、要素が複数あるため方法分からず。
    スマートフォン/携帯電話のカテゴリを選択
    category_child.select_by_visible_text('スマートフォン/携帯電話')
    value値でも(ry
    category_child.select_by_value('100')
    """

    # スマートフォン本体のチェックボックスをon
    category_chkbox = driver.find_element_by_xpath(
        '/html/body/div[1]/main/div[2]/form/div[2]/div[2]/div[3]/div[91]/div[1]/label')
    category_chkbox.click()

    # submit
    submit = driver.find_element_by_tag_name('button')
    submit.click()
    """
    ここまで長々と、検索設定してきたが、
    予め設定した条件で一度検索かけると、URLに
    検索パラメータが反映されるので、検索結果が欲しいだけなら
    上記の個々設定をプログラムでやる必要はない。
    seleniumの学習の一貫で調べたまで
    """


def get_item(driver):
    """
    検索結果を取得する
    """
    global count
    search_limit = 100

    items = driver.find_elements_by_class_name('items-box')
    for item in items:

        count += 1
        if count > search_limit:
            break

        print('----------------------------------------------------------')
        print('#', count)
        # 商品リンク
        print(item.find_element_by_tag_name('a').get_attribute('href'))
        # 商品タイトル
        print(item.find_element_by_tag_name('h3').text)
        # 商品画像
        print(item.find_element_by_tag_name('img').get_attribute('data-src'))
        # 価格
        print(item.find_element_by_class_name('items-box-price').text)

    # やりすぎ注意
    if count > search_limit:
        return

    # 次のページがあれば処理を繰り返す
    next_page = driver.find_element_by_class_name('pager-next')
    if next_page.is_displayed() is True:
        next_page.find_element_by_tag_name('a').click()
        get_item(driver)


if __name__ == '__main__':
    main()

リファクタリングの余地あり!!笑

なお結果はこんな感じで出力されます。

----------------------------------------------------------
# 1
https://item.mercari.com/jp/m38547876320/
iPhoneX
https://static-mercari-jp-imgtr2.akamaized.net/thumb/photos/m38547876320_1.jpg?1532585075
¥ 90,000
----------------------------------------------------------
# 2
https://item.mercari.com/jp/m25321697532/
iPhone 7 Plus Jet Black 128 GB SIMフリー
https://static-mercari-jp-imgtr2.akamaized.net/thumb/photos/m25321697532_1.jpg?1532585087
¥ 60,000
----------------------------------------------------------

(省略)

----------------------------------------------------------
# 100
https://item.mercari.com/jp/m22103423090/
SIMフリー iPhoneX 64GB
https://static-mercari-jp-imgtr2.akamaized.net/thumb/photos/m22103423090_1.jpg?1532431094
¥ 85,000

プロセスは終了コード 0 で完了しました

所感:関数の構造がこれが正解なのか分からん。また、xpathで書いているところの「これじゃ駄目だ」感が拭えない。件数が0件だった時、その他エラーハンドリングまでは全く考慮されていない。 これ作るのに約半日かかった。まだまだ。

次はcsvやDBに入れるまでをやってみようと思います。