国立市のカフェをスクレイピングしたいのですが、うまくいきません。
データフレームに何も入ってない状態で出力されるので、データが取れていないということでしょうか。
・やったこと
import requests from bs4 import BeautifulSoup import re import pandas as pd import time class Tabelog: """ 食べログスクレイピングクラス test_mode=Trueで動作させると、最初のページの3店舗のデータのみを取得できる """ def __init__(self, base_url, test_mode=False, p_ward='東京都内', begin_page=1, end_page=30): # 変数宣言 self.store_id = '' self.store_id_num = 0 self.store_name = '' self.score = 0 self.ward = p_ward self.review_cnt = 0 self.review = '' self.columns = ['store_id', 'store_name', 'score', 'ward', 'review_cnt', 'review'] self.df = pd.DataFrame(columns=self.columns) self.__regexcomp = re.compile(r'\n|\s') # \nは改行、\sは空白 page_num = begin_page # 店舗一覧ページ番号 if test_mode: list_url = base_url + str(page_num) + '/?Srt=D&SrtT=rt&sort_mode=1' #食べログの点数ランキングでソートする際に必要な処理 self.scrape_list(list_url, mode=test_mode) else: while True: list_url = base_url + str(page_num) + '/?Srt=D&SrtT=rt&sort_mode=1' #食べログの点数ランキングでソートする際に必要な処理 if self.scrape_list(list_url, mode=test_mode) != True: break # INパラメータまでのページ数データを取得する if page_num >= end_page: break page_num += 1 return def scrape_list(self, list_url, mode): """ 店舗一覧ページのパーシング """ r = requests.get(list_url) if r.status_code != requests.codes.ok: return False soup = BeautifulSoup(r.content, 'html.parser') soup_a_list = soup.find_all('a', class_='list-rst__rst-name-target') # 店名一覧 if len(soup_a_list) == 0: return False if mode: for soup_a in soup_a_list[:2]: item_url = soup_a.get('href') # 店の個別ページURLを取得 self.store_id_num += 1 self.scrape_item(item_url, mode) else: for soup_a in soup_a_list: item_url = soup_a.get('href') # 店の個別ページURLを取得 self.store_id_num += 1 self.scrape_item(item_url, mode) return True def scrape_item(self, item_url, mode): """ 個別店舗情報ページのパーシング """ start = time.time() r = requests.get(item_url) if r.status_code != requests.codes.ok: print(f'error:not found{ item_url }') return soup = BeautifulSoup(r.content, 'html.parser') # 店舗名称取得 # <h2 class="display-name"> # <span> # 国立 サーカス # </span> # </h2> store_name_tag = soup.find('h2', class_='display-name') store_name = store_name_tag.span.string print('{}→店名:{}'.format(self.store_id_num, store_name.strip()), end='') self.store_name = store_name.strip() # カフェ以外の店舗は除外 store_head = soup.find('div', class_='rdheader-subinfo') # 店舗情報のヘッダー枠データ取得 store_head_list = store_head.find_all('dl') store_head_list = store_head_list[1].find_all('span') #print('ターゲット:', store_head_list[0].text) if store_head_list[0].text not in {'カフェ'}: print('カフェではないので処理対象外') self.store_id_num -= 1 return # 評価点数取得 rating_score_tag = soup.find('b', class_='c-rating__val') rating_score = rating_score_tag.span.string print(' 評価点数:{}点'.format(rating_score), end='') self.score = rating_score # 評価点数が存在しない店舗は除外 if rating_score == '-': print(' 評価がないため処理対象外') self.store_id_num -= 1 return # レビュー一覧URL取得 #<a class="mainnavi" href="https://tabelog.com/tokyo/A1325/A132503/13205822/dtlrvwlst/"><span>口コミ</span><span class="rstdtl-navi__total-count"><em>60</em></span></a> review_tag_id = soup.find('li', id="rdnavi-review") review_tag = review_tag_id.a.get('href') # レビュー件数取得 print(' レビュー件数:{}'.format(review_tag_id.find('span', class_='rstdtl-navi__total-count').em.string), end='') self.review_cnt = review_tag_id.find('span', class_='rstdtl-navi__total-count').em.string # レビュー一覧ページ番号 page_num = 5 #1ページ*20 = 20レビュー 。この数字を変えて取得するレビュー数を調整。 def scrape_review(self, review_url): """ レビュー一覧ページのパーシング """ r = requests.get(review_url) if r.status_code != requests.codes.ok: print(f'error:not found{ review_url }') return False # データフレームの生成 self.make_df() return def make_df(self): self.store_id = str(self.store_id_num).zfill(8) #0パディング se = pd.Series([self.store_id, self.store_name, self.score, self.review_cnt], self.columns) # 行を作成 self.df = self.df.append(se, self.columns) # データフレームに行を追加 return kunitachi_cafe_review = Tabelog(base_url="https://tabelog.com/tokyo/C13215/rstLst/cafe",test_mode=False, p_ward='国立') #出力 kunitachi_cafe_review.df
・参考にしたもの
https://qiita.com/toshiyuki_tsutsui/items/f143946944a428ed105b