Как исправить код для очистки веб-сайта Zomato?
Я написал этот код, но получил это как ошибку "IndexError: индекс списка вне допустимого диапазона" после выполнения последней строки. Пожалуйста, как мне это исправить?
import requests
from bs4 import BeautifulSoup
headers = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML,
like Gecko) Chrome/61.0.3163.100 Safari/537.36'}
response = requests.get("https://www.zomato.com/bangalore/top-restaurants",headers=headers)
content = response.content
soup = BeautifulSoup(content,"html.parser")
top_rest = soup.find_all("div",attrs={"class": "sc-bblaLu dOXFUL"})
list_tr = top_rest[0].find_all("div",attrs={"class": "sc-gTAwTn cKXlHE"})
list_rest =[]
for tr in list_tr:
dataframe ={}
dataframe["rest_name"] = (tr.find("div",attrs={"class": "res_title zblack bold nowrap"})).text.replace('\n', ' ')
dataframe["rest_address"] = (tr.find("div",attrs={"class": "nowrap grey-text fontsize5 ttupper"})).text.replace('\n', ' ')
dataframe["cuisine_type"] = (tr.find("div",attrs={"class":"nowrap grey-text"})).text.replace('\n', ' ')
list_rest.append(dataframe)
list_rest
3 ответа
Недавно я выполнил проект, который заставил меня исследовать парсинг веб-сайта Zomato в Маниле, Филиппины. Я использовал Geolibrary, чтобы получить значения долготы и широты Манилы, а затем с помощью этой информации соскребал детали ресторанов. ДОБАВИТЬ: Вы можете получить свой собственный ключ API на сайте zomato, чтобы совершать до 1000 звонков в день.
# Use geopy library to get the latitude and longitude values of Manila City.
from geopy.geocoders import Nominatim
address = 'Manila City, Philippines'
geolocator = Nominatim(user_agent = 'Makati_explorer')
location = geolocator.geocode(address)
latitude = location.lenter code hereatitude
longitude = location.longitude
print('The geographical coordinate of Makati City are {}, {}.'.format(latitude, longitude))
# Use Zomato's API to make call
headers = {'user-key': '617e6e315c6ec2ad5234e884957bfa4d'}
venues_information = []
for index, row in foursquare_venues.iterrows():
print("Fetching data for venue: {}".format(index + 1))
venue = []
url = ('https://developers.zomato.com/api/v2.1/search?q={}' +
'&start=0&count=1&lat={}&lon={}&sort=real_distance').format(row['name'], row['lat'], row['lng'])
try:
result = requests.get(url, headers = headers).json()
except:
print("There was an error...")
try:
if (len(result['restaurants']) > 0):
venue.append(result['restaurants'][0]['restaurant']['name'])
venue.append(result['restaurants'][0]['restaurant']['location']['latitude'])
venue.append(result['restaurants'][0]['restaurant']['location']['longitude'])
venue.append(result['restaurants'][0]['restaurant']['average_cost_for_two'])
venue.append(result['restaurants'][0]['restaurant']['price_range'])
venue.append(result['restaurants'][0]['restaurant']['user_rating']['aggregate_rating'])
venue.append(result['restaurants'][0]['restaurant']['location']['address'])
venues_information.append(venue)
else:
venues_information.append(np.zeros(6))
except:
pass
ZomatoVenues = pd.DataFrame(venues_information,
columns = ['venue', 'latitude',
'longitude', 'price_for_two',
'price_range', 'rating', 'address'])
Вы получаете эту ошибку, потому что top_rest пуст, когда вы пытаетесь получить первый его элемент "top_rest[0]". Причина в том, что первый класс, на который вы пытаетесь сослаться, имеет динамическое имя. Вы заметите, что если вы обновите страницу, одно и то же расположение этого div не будет названо одинаково. Поэтому, когда вы пытаетесь очистить, вы получаете пустые результаты.
Альтернативой было бы очистить ВСЕ div, а затем сузить круг элементов, которые вы хотите, помните о динамической схеме именования div, чтобы от одного запроса к другому вы получали разные результаты:
import requests
from bs4 import BeautifulSoup
headers = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36'}
response = requests.get("https://www.zomato.com/bangalore/top-restaurants",headers=headers)
content = response.content
soup = BeautifulSoup(content,"html.parser")
top_rest = soup.find_all("div")
list_tr = top_rest[0].find_all("div",attrs={"class": "bke1zw-1 eMsYsc"})
list_tr
Используя язык веб-парсинга, я смог написать следующее:
GOTO https://www.zomato.com/bangalore/top-restaurants
EXTRACT {'rest_name': '//div[@class="res_title zblack bold nowrap"]',
'rest_address': '//div[@class="nowrap grey-text fontsize5 ttupper',
'cusine_type': '//div[@class="nowrap grey-text"]'} IN //div[@class="bke1zw-1 eMsYsc"]
Это будет перебирать каждый элемент записи с классом bke1zw-1 eMsYsc
и вытащите информацию о каждом ресторане.