前提・実現したいこと
食べログで東京都内、星3.5以上のラーメン屋情報のスクレイピングをしています。
「店名、住所、評価点数」を1行としてデータフレームを作成し、csv書き出しをしたいです。
発生している問題・エラーメッセージ
「店名、住所、評価点数」を1行としたデータフレームが生成されません。
また、星3.67以上の情報はアウトプットできるのですが、3.67未満から動作がストップしてしまいます。
該当のソースコード
import requests
from bs4 import BeautifulSoup
import re
import pandas as pd
import time
import csv
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.address_name = "" self.columns = ['store_id', 'store_name', 'score','address_name'] 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('ラーメンorつけ麺のお店ではないので処理対象外') self.store_id_num -= 1 return ####住所取得 ####<p class="rstinfo-table__address"> #### <span> #### <a href="/tokyo/" class="listlink"> #### 東京都 #### </a> #### </span> #### <span> #### <a href="/tokyo/C13104/rstLst/" class="listlink"> #### 新宿区 #### </a> #### <a href="/tokyo/C13104/C36218/rstLst/" class="listlink"> #### 歌舞伎町 #### </a> #### 1-9-5 #### </span> #### <span> #### 三経61ビル 2F #### </span> #### </p> try: address_name = soup.find("p", class_="rstinfo-table__address").text print(" 住所:{}".format(address_name), end="") self.address_name = address_name except AttributeError: href = '' #### 評価点数取得 ####<b class="c-rating__val rdheader-rating__score-val" rel="v:rating"> #### <span class="rdheader-rating__score-val-dtl">3.58</span> ####</b> 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 #### 評価が3.5未満店舗は除外 if float(rating_score) < 3.5: print(' 食べログ評価が3.5未満のため処理対象外') self.store_id_num -= 1 return #### データフレームの生成 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.address_name, self.score], self.columns) # 行を作成 self.df = self.df.append(se, self.columns) # データフレームに行を追加 return
###実行
tokyo_ramen_address = Tabelog(base_url="https://tabelog.com/tokyo/rstLst/ramen/",test_mode=False)
tokyo_ramen_address.df.to_csv("Users/〜〜〜〜/Desktop/tokyo_ramen_address.csv")
試したこと
https://qiita.com/toshiyuki_tsutsui/items/f143946944a428ed105b
上記URLの方のブログのコードを元に、住所情報をスクレイピングするためにコードをアレンジしました。
住所情報を取り出すことは出来たのですが、それが綺麗にデータフレームとしてアウトプットできず、また星3.5まで取り出しきれない状況です。
(上記URLのコードをそのまま試した際は、データフレームに収まり上手くいったのですが。。)
補足情報(FW/ツールのバージョンなど)
Python、スクレイピングを勉強し始めたばかりの初心者です。mac OS、Jupyter Notebookで取り組んでいます。
皆さま恐れ入りますがご教示いただけますと幸いです。何卒よろしくお願いいたします。
回答1件
あなたの回答
tips
プレビュー