I've written a script in python to parse different names and phone numbers of various restaurant names from yelp.com. The scraper is doing its job just fine. The most important feature of this scraper is that it can handle pagination on the fly (if there is any) no matter how many pages it traverses. I tried to create it following the guidelines of OOP. However, I suppose there are still some options to make it better, as in isolating the while True
loop by storing it in another function.
This is the script:
import requests
from urllib.parse import quote_plus
from bs4 import BeautifulSoup
class YelpScraper:
link = 'https://www.yelp.com/search?find_desc={}&find_loc={}&start={}'
def __init__(self, name, location, num="0"):
self.name = quote_plus(name)
self.location = quote_plus(location)
self.num = quote_plus(num)
self.base_url = self.link.format(self.name,self.location,self.num)
self.session = requests.Session()
def get_info(self):
s = self.session
s.headers = {'User-Agent': 'Mozilla/5.0'}
while True:
res = s.get(self.base_url)
soup = BeautifulSoup(res.text, "lxml")
for items in soup.select("div.biz-listing-large"):
name = items.select_one(".biz-name span").get_text(strip=True)
try:
phone = items.select_one("span.biz-phone").get_text(strip=True)
except AttributeError: phone = ""
print("Name: {}\nPhone: {}\n".format(name,phone))
link = soup.select_one(".pagination-links .next")
if not link:break
self.base_url = "https://www.yelp.com" + link.get("href")
if __name__ == '__main__':
scrape = YelpScraper("Restaurants","San Francisco, CA")
scrape.get_info()