メルカリの商品をスクレイピングする

Seleniumを使ってメルカリで商品を検索して、BeautifulSoupで購入可能なものだけをまとめさせるというものを作っていきたいと思います。 実際にコードを書く前に、簡単なロジックを考えていきたいと思います。Seleniumの導入の方法などはQiitaに書いたのでこちら

1.メルカリの商品を検索する
2.ページから商品の名前と値段、URLを所得する。
3.それぞれの商品のURLに移動し、購入可能か不可能かを判別する。

これらの流れをスクリプトで書いていきたいと思います。

word = 'Python3'
URL = 'https://www.mercari.com/jp/search/?keyword='+word

browser = webdriver.PhantomJS('/home/yasudaak/myenv/bin/phantomjs')
browser.set_window_size(1920, 1080)
browser.get(URL)

検索するキーワード(今回はPython3)をURLに入力してそのURLを検索しています。

html = browser.page_source
soup = BeautifulSoup(html,"lxml")
#ページ内の商品名と値段を取り出す(購入可能か購入不可能かは関係なく)。
div = soup.find_all("div", class_="items-box-price font-5")
h3 = soup.find_all("h3", class_="items-box-name font-2")
#商品の値段をprice_listに追加する(購入可能か購入不可能かは関係なくすべての商品)
for price in div:
    price_list.append(price.string)
#商品名をname_listに追加する(購入可能か購入不可能かは関係なくすべての商品)
for name in h3:
    name_list.append(name.string)
#検索TOPのページ内のaタグの中からhref属性に/item.mercari.com/jp/が含まれるもの(商品のリンク)をurl_listに追加する。
for link in soup.find_all("a"):
    if "/item.mercari.com/jp/" in link.get("href"):
        url_list.append(link.get("href"))

検索したページのHTMLを所得し、商品名と値段、URLを取り出してそれぞれをリストに追加しています。

検索TOPのページ

#url_list内のリンクをSeleniumで検索して個別の商品のページ内のHTMLのソースにdiv class="item-buy-btn disabled f18-24"がなかったら購入可能なのでenable_buy_url_listに追加して、url_list内で何番目かをurl_number_listに追加する。
for test_link in range(len(url_list)):
    link_number = url_list[n]
    browser.get(link_number)
    html = browser.page_source
    soup = BeautifulSoup(html,"lxml")
    time.sleep(1)
    if not soup.find_all("div", class_="item-buy-btn disabled f18-24"):
        print("購入可能です")
        enable_buy_url_list.append(link_number)
        url_number_list.append(n)
        n+=1
    else:
        print("購入不可能です!!")
        n+=1

先ほど取り出した商品のURLを検索して、それらが購入可能か、購入不可能かを判別しています。

購入不可能の時

購入可能の時

#name_listとprice_listから購入可能なものを取り出してenable_buy_name_listとenable_buy_price_listにそれぞれ追加する。
for xxx in range(len(url_number_list)):
    enable_buy_name_list.append(name_list[url_number_list[xxx]])
    enable_buy_price_list.append(price_list[url_number_list[xxx]])

購入可能なものだけを全商品名リストと値段リストから取り出しています。

以下が上のものをまとめた全コードです。

#coding: utf-8
#!/usr/bin/env python
import time
from selenium import webdriver
from bs4 import BeautifulSoup


name_list = []
price_list = []
url_list = []
enable_buy_url_list = []
enable_buy_name_list = []
url_number_list = []
enable_buy_price_list = []
n = 0
word = 'Python3'
URL = 'https://www.mercari.com/jp/search/?keyword='+word

browser = webdriver.PhantomJS('/home/yasudaak/myenv/bin/phantomjs')
browser.set_window_size(1920, 1080)
browser.get(URL)

html = browser.page_source
soup = BeautifulSoup(html,"lxml")
#ページ内の商品名と値段を取り出す(購入可能か購入不可能かは関係なく)。
div = soup.find_all("div", class_="items-box-price font-5")
h3 = soup.find_all("h3", class_="items-box-name font-2")
#商品の値段をprice_listに追加する(購入可能か購入不可能かは関係なくすべての商品)
for price in div:
    price_list.append(price.string)
#商品名をname_listに追加する(購入可能か購入不可能かは関係なくすべての商品)
for name in h3:
    name_list.append(name.string)
#検索TOPのページ内のaタグの中からhref属性に/item.mercari.com/jp/が含まれるもの(商品のリンク)をurl_listに追加する。
for link in soup.find_all("a"):
    if "/item.mercari.com/jp/" in link.get("href"):
        url_list.append(link.get("href"))
#url_list内のリンクをseleniumで検索して個別の商品のページ内のHTMLのソースにdiv class="item-buy-btn disabled f18-24"がなかったら購入可能なのでenable_buy_url_listに追加して、url_list内で何番目かをurl_number_listに追加する。
for test_link in range(len(url_list)):
    link_number = url_list[n]
    browser.get(link_number)
    html = browser.page_source
    soup = BeautifulSoup(html,"lxml")
    time.sleep(1)
    if not soup.find_all("div", class_="item-buy-btn disabled f18-24"):
        print("購入可能です")
        enable_buy_url_list.append(link_number)
        url_number_list.append(n)
        n+=1
    else:
        print("購入不可能です!!")
        n+=1
#name_listとprice_listから購入可能なものを取り出してenable_buy_name_listとenable_buy_price_listにそれぞれ追加する。
for xxx in range(len(url_number_list)):
    enable_buy_name_list.append(name_list[url_number_list[xxx]])
    enable_buy_price_list.append(price_list[url_number_list[xxx]])
#購入可能な商品の商品名、値段、URLをそれぞれ表示する。
print(enable_buy_name_list)
print(enable_buy_price_list)
print(enable_buy_url_list)

browser.close()
browser.quit()

工夫した点

全商品の名前、値段のリストから(それぞれname_list、price_list)、購入可能なものを取り出すために、購入可能な商品のURLがすべての商品のURLリストである(url_list)の何番目であるかをurl_number_listに追加する。 その番号のものをname_list、price_listから取り出してそれぞれをenable_buy_name_list、enable_buy_price_listに追加したところ。

「次のページに移動する」は、今回は実装しませんでした。
販売中だけを表示する詳細検索があることをこれを書いたあとに知った…

何をやっているかわからない人に

すべての商品がABCDEFGの7つだけだと仮定します。 実際に購入可能な商品はACDFの4つだとしたときに全てのリストに入っているものは以下のようになります。 〇は何も入っていないことを表します。

全ての商品名(name_list) ⒶⒷⒸⒹⒺⒻⒼ
全ての値段(price_list) ⒶⒷⒸⒹⒺⒻⒼ
全てのURL(url_list) ⒶⒷⒸⒹⒺⒻⒼ
買えるものだけのURL(enable_buy_url_list) Ⓐ〇ⒸⒹ〇Ⓕ〇
enable_buy_url_list内の要素が何番目にあるか(url_number_list) ⓪➁➂➄〇〇〇
買えるものだけの商品名(enable_buy_name_list) ⒶⒸⒹⒻ〇〇〇
買えるものだけの値段(enable_buy_price_list) ⒶⒸⒹⒻ〇〇〇