BeautifulSoupを使って全国の美味い店の情報を取得してみた

Rettyで特集されている全国の美味しいレストランの情報を取得してみた。
BeautifulSoupについて知りたい方は BeautifulSoupを使ってスクレイピングをしてみるを読んでください。

取得できる情報は

  • 店の名前
  • 電話番号
  • ランチの予算
  • ディナーの予算
  • 店の画像
  • 営業時間の備忘録
となっています。

PREFS = None


"""
URL
PRE01: 北海道
http://retty.me/area/PRE01/ -> 北海道グルメに関するまとめ -> n -> 店舗一覧
PRE47: 沖縄 -
http://retty.me/area/PER47/  -> 沖縄グルメに関するまとめ -> n -> 店舗一覧
○○○グルメに関するまとめのサブリンクからすべて取得するようにする。
"""


class Scrape(object):

    """
    Updates the overall_score field of every user.
    """

    def text_removed_tag(self,html,tag_name):
        """
        Return text removed tag name.
        :param html:
        :param tag_name:
        :return: html
        """

        a = html.replace('<{}>'.format(tag_name),'')\
            .replace(''.format(tag_name),'').strip(' ')
        return a.decode('utf-8')


    def get_price_from_text(self,text,eat_time):
        pattern = None
        if eat_time == 'dinner':
            pattern = u"(.)*\(ディナー\)~"
        elif eat_time == 'lunch':
            pattern = u"(.)*\(ランチ\)~"

        match = re.match(pattern,text)
        if match is None:
            return

        end =  match.end()
        return text[end:end+4].strip(' ').encode('utf-8')


    def get_topics_from_pref(self,pref_url):
        """
        dd .main_topics
        :param topic_url:  (ex) http://retty.me/area/PRE01/
        :return:  topic_urls: list(topic_url)
        """

        r = requests.get(pref_url)
        soup = BeautifulSoup(r.text.encode(r.encoding))
        _urls =  soup.find('ul',{'class':'main_topics'}).find_all('a')
        pref_name = soup.find('h1').get_text().replace(u'グルメ・レストラン情報',
                                                       u'').encode('utf-8')
        res = []
        print pref_name
        for url in _urls:
            res.append(url.get('href'))
        return res

    def get_restaurants_from_topic_url(self,topic_url):
        """
        :param topic_url: トピック別のURL
        :return: トピック事の店一覧
        """
                # 都道府県からランダムにアクセスして餃子とか別の特集食物にアクセスしたい
        # 北海道:餃子

        r = requests.get(topic_url)
        soup = BeautifulSoup(r.text.encode(r.encoding))
        restaurants = soup.find_all('div',{'class': 'restaurant'})
        res = []
        _pref_num = topic_url.split('/')[4].replace('PRE','')
        pref_num = _pref_num[1] if _pref_num[0] == '0' else _pref_num
        pref_name = None
        # Get Restaurants from prefecture.
        for restaurant in restaurants:

            # Get Address
            info_dl = restaurant.find('dl',{'class':'info'})
            dd = BeautifulSoup(str(info_dl)).find_all('dd')
            if len(dd) < 1:
                continue
            address = self.text_removed_tag(str(dd[1]),'dd')
            price_text = self.text_removed_tag(str(dd[0]), 'dd')

            lunch_price = self.get_price_from_text(price_text,'lunch')
            dinner_price = self.get_price_from_text(price_text,'dinner')

            tel =  restaurant.find('dd',{'class': 'tel'}).get_text()
            business_hours = dd[3].get_text().replace(r'/\n/',' ')

            # Get image
            imagehtmls = restaurant.find_all('img')
            for imagehtml in imagehtmls:

                if 'display_image' in str(imagehtml) and 'facebook' not in \
                        str(imagehtml):
                    image =  imagehtml.get('data-image')
                    restaurant_name = imagehtml.get('alt').replace(u'の写真','')
                    res.append({
                        'img_thumb':image,
                        'img_large':image,
                        'restaurant_name': restaurant_name,
                        'address': address,
                        'lunch_price': lunch_price, #ランチの予算
                        'dinner_price': dinner_price, #デイナーの予算
                        'tel': tel,#電話暗号
                        'business_hours': business_hours,#営業時間
                        'pref_name': self.get_pref_name(pref_num),#都道府県
                    })

       

        return res

    def get_pref_name(self,pref_num):
        return PREFS[int(pref_num) - 1]['pref_name']

    def pref_num_to_num(self):
        pass
    def build_pref_url(self,pref_num):
        if pref_num < 10:
            return 'http://retty.me/area/PRE0{}/'.format(pref_num)
        else:
            return 'http://retty.me/area/PRE{}/'.format(pref_num)




    def setup(self):
        """
        PREFSに書き出す
        :return: list_pref: write out as  pref.json file.
        """
        res = []
        for i in range(1,48):
            pref_url = self.build_pref_url(i)
            r = requests.get(pref_url)

            soup = BeautifulSoup(r.text.encode(r.encoding))

            pref_name = soup.find('h1').get_text().replace(u'グルメ・レストラン情報',
                                                           u'').encode('utf-8')

            item = {
                'num': i,
                'pref_name': pref_name
            }
            res.append(item)
        return res



   
         

実行

   s = Scrape()
   prefs = s.cmd_setup()
   restaurants = []
   for i in range(1,48):
       pref_url = s.build_pref_url(i)
       topic_urls = s.get_topics_from_pref(pref_url)
       for topic_url in topic_urls:
           restaurants.append(s.get_restaurants_from_topic_url(topic_url))

   print restaurants[0]['restaurant_name'] #-> 中華料理 香州


Related Contents

Pickup Contents