メルカリをスクレイピングして商品リンク、画像、価格を取得する
タイトルの通り!
要素の取得方法など勉強がてら、みんな大好きスクレイピングを実装しました。 ここまで出来れば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件だった時、その他エラーハンドリングまでは全く考慮されていない。 これ作るのに約半日かかった。まだまだ。