LoginSignup
1
1

More than 3 years have passed since last update.

【学習記録】seleniumで食べログをスクレイピング

Last updated at Posted at 2020-05-18

python学習記録

 Udemyで『PythonによるWebスクレイピング〜入門編〜【業務効率化への第一歩】』を学習したので、何か実験したい!と思いました。 株価を取得してデータを分析、コロナ関係の記事・口コミをスクレイピングして自然言語処理してみる・・・とか色々考えましたけれど、今の自分の知識では何をどうすれば良いかサッパリ分かりません。

 そこで、食べログの店名と評価のデータをとりあえず収集してみよう!と思いました。 食べログの規約を見ても、スクレイピングについては記載は無かった(集めたデータを商用転用するのはNG)ので、サーバーに過負荷をかけないように気をつけながら試したいと思います。 jupyter notebookで下記のコードを作って、動かしてみました。

python3:taberogu_scraping.py

import pandas as pd
import time
from selenium import webdriver

browser = webdriver.Chrome("/usr/lib/chromium-browser/chromedriver")

#テスト駆動用
browser.get('https://tabelog.com/shizuoka/A2201/rstLst/1/')
#メインのカラムを取得
elem_restlist = browser.find_element_by_class_name('js-rstlist-inforstlist-info')
#個々の店のブロックを取得
elem_list_rst = elem_restlist.find_elements_by_class_name('list-rst__wrap.js-open-new-window')
#個々のブロックのメイン部を取得
list_rst_body = elem_list_rst[0].find_element_by_class_name('list-rst__body')
#評価を取得
rank = list_rst_body.find_element_by_class_name('c-rating__val').text
#キャッチコピーを取得
cpy_title = list_rst_body.find_element_by_class_name('list-rst__pr-title').text

#本番用
rank_list = []
cpy_title_list = []
rst_name_list = []

#店名の取得を関数化
def get_rst_name(elem_list_rst):
    for rsts in range(len(elem_list_rst)):
        rst_name = elem_list_rst[rsts].find_element_by_class_name('list-rst__rst-name-target.cpy-rst-name').text
        rst_name_list.append(rst_name)

#関数(メソッド)化
def get_rank_and_cpy_title(elem_list_rst):
    for txt in range(len(elem_list_rst)):
        #個々のブロックのメイン部を取得
        list_rst_body = elem_list_rst[txt].find_element_by_class_name('list-rst__body')
        rank = list_rst_body.find_element_by_class_name('c-rating__val').text
        rank_list.append(rank)
        #ランクが登録されていないと'c-rating__val'が生成されずNoneが取得されるため、.textがエラーになるのを防ぐ
        try:
            cpy_title = list_rst_body.find_element_by_class_name('list-rst__pr-title').text
            cpy_title_list.append(cpy_title)
        except:
            cpy_title_list.append(None)

for pages in range(1,60): #食べログは60p以降表示出来ない
    browser.get('https://tabelog.com/shizuoka/A2201/rstLst/{}/'.format(pages))
    elem_restlist = browser.find_element_by_class_name('js-rstlist-info.rstlist-info')
    elem_list_rst = elem_restlist.find_elements_by_class_name('list-rst__wrap.js-open-new-window')
    get_rst_name(elem_list_rst)
    get_rank_and_cpy_title(elem_list_rst)
    time.sleep(10)

#データをデータフレーム化後、csvで保存
df = pd.DataFrame()
df['店名'] = rst_name_list
df['評価'] = rank_list
df['キャッチコピー'] = cpy_title_list
df.to_csv('食べログランキング.csv')

 リンクを辿って、個々の店のページをスクレイピングする、いわゆる'クローリング'はまだ実装出来ていません。 勉強中です、はい。リクエストを送るスピードはどれくらいがいいのか調べて、この方の意見を参考に、10秒に1回で設定してみました。

つまづいたところ

     
  1. 評価やキャッチコピーが設定されていないお店は、対象としたタグが生成されず、エラーが帰ってくる。
  2.  
  3. 食べログのページ数が多すぎると、60P以降はスクレイピング出来ない

 1に関しては、try文でエラーを回避してみました。とりあえず動いたけれど、使い方はあっているのだろうか? 
 2に関しては、取得件数を表示件数で割って、ページ数を計算してスクレイピングしてたら、60P目で止まってしまった。食べログのWEBページには、件数しぼって再検索してください、との事。まあ、そうですよね。こちらはページ数を60で固定。ってこれ60P以下だとエラー出るのかな?まだ試していない。

ステップアップに向けて

 リンクを辿ってスクレイピングする'クローリング'技術を身につける。取得したデータを分析する。分析したデータを使って、WEBアプリをつくる。

1
1
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1