#python #web-scraping #missing-data #review
#python #веб-очистка #отсутствует-данные #обзор
Вопрос:
Я пытаюсь очистить некоторые данные со страницы yelp. Однако некоторые значения отсутствуют, когда я получаю результат, и отсутствующие данные изменяются каждый раз, когда я выполняю код (например: при первом выполнении отсутствуют 2 данные, при втором выполнении 1 данные отсутствуют). Вы, ребята, знаете, почему это происходит? Спасибо!!
import time
review_listings= []
cols2 = ['restaurant name','username','ratings','review.text']
copy = 0
for url in data_rev['url']: # Each url has 20 so start
start = time.time()
for p in pages:
url_review = url "amp;start={}".format(str(p))
page = r.get(url_review)
soup = BeautifulSoup(page.content,'html.parser')
res_name = soup.find("h1",{"class":"lemon--h1__373c0__2ZHSL heading--h1__373c0___56D3 undefined heading--inline__373c0__1jeAh"}).text
tables=soup.findAll('li',{'class':'lemon--li__373c0__1r9wz margin-b3__373c0__q1DuY padding-b3__373c0__342DA border--bottom__373c0__3qNtD border-color--default__373c0__3-ifU'})
if(len(tables) == 0):
print(url_review)
break
else:
for table in tables:
#name,ratings,username:
username = table.find("span",{"class":"lemon--span__373c0__3997G text__373c0__2Kxyz fs-block text-color--blue-dark__373c0__1jX7S text-align--left__373c0__2XGa- text-weight--bold__373c0__1elNz"}).a.text
ratings = table.find("span",{"class":"lemon--span__373c0__3997G display--inline__373c0__3JqBP border-color--default__373c0__3-ifU"}).div.get("aria-label")
text = table.find("span",{"class":"lemon--span__373c0__3997G raw__373c0__3rKqk"}).text
review_listings.append([res_name,username,ratings,text])
rev_df = pd.DataFrame.from_records(review_listings,columns=cols2)
size_df = len(rev_df)
print("review sizes are =>",size_df - copy)
print(res_name)
copy = size_df
end = time.time()
print(end-start)
Комментарии:
1. не могли бы вы поделиться каким-нибудь примером
url
?3. @user14245642 используйте
Selenium
вместоBeautifulSoup
4. @ZarakiKenpachi Я тоже думал об этом, но мне нужно очистить более тысячи данных, поэтому это займет слишком много времени, если я использую Selenium.
5. Высока вероятность того, что используемые вами классы являются динамическими, чтобы избежать очистки
Ответ №1:
Похоже, что все интересующие вас данные хранятся как json
в источнике страницы. Это может быть более надежным способом получения информации с этой страницы:
import re
import json
import requests
## Using headers is always a good pratice
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:80.0) Gecko/20100101 Firefox/80.0',
'Accept': 'text/html,application/xhtml xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
'Accept-Language': 'fr,fr-FR;q=0.8,en-US;q=0.5,en;q=0.3',
'Connection': 'keep-alive',
'Upgrade-Insecure-Requests': '1',
'Pragma': 'no-cache',
'Cache-Control': 'no-cache',
}
response = requests.get('https://www.yelp.com/biz/saku-vancouver-3', headers=headers)
soup = BeautifulSoup(response.content)
# Lets find the 'script' tag which contains restaurant's information
data_tag = soup.find('script',text = re.compile('"@type":'))
#Load it properly as json
data = json.loads(data_tag.text)
print(data)
Вывод
{'@context': 'https://schema.org',
'@type': 'Restaurant',
'name': 'Saku',
'image': 'https://s3-media0.fl.yelpcdn.com/bphoto/_TjVeAVRczn0yITxvBqrCA/l.jpg',
'priceRange': 'CA$11-30',
'telephone': '',
'address': {'streetAddress': '548 W Broadway',
'addressLocality': 'Vancouver',
'addressCountry': 'CA',
'addressRegion': 'BC',
'postalCode': 'V5Z 1E9'},
'review': [{'author': 'Jackie L.',
'datePublished': '1970-01-19',
'reviewRating': {'ratingValue': 5},
'description': 'With restaurants .... }
...]
}
Комментарии:
1. Спасибо за ваш ответ, но он выдает ошибку: JSONDecodeError: Ожидаемое значение: строка 1, столбец 1 (символ 0)
2. Вы протестировали это с помощью URL-адреса, который вы мне предоставили? Если это так, возможно, ваш IP временно занесен в черный список
Ответ №2:
Попробуйте следующее, чтобы получить название ресторана, все имена рецензентов, их отзывы, рейтинги на нескольких страницах. Конечно, если вы еще не были заблокированы этим сайтом.
import requests
url = 'https://www.yelp.com/biz/XAH2HpuUUtu7CUO26pbs4w/review_feed?'
params = {
'rl': 'en',
'sort_by': 'relevance_desc',
'q': '',
'start': ''
}
page = 0
while True:
params['start'] = page
res = requests.get(url,params=params)
if not res.json()['reviews']:break
for item in res.json()['reviews']:
restaurant = item['business']['name']
rating = item['rating']
user = item['user']['markupDisplayName']
review = item['comment']['text']
print(restaurant,rating,user,review)
page =20
Комментарии:
1. Вы пробовали скрипт @user14245642?