Иногда я собираю обзоры Steam с помощью Steam Web API для личного использования, и следующий код, хотя и содержит некоторые избыточные части, может собирать все обзоры для данной игры. В последнее время я пытался собирать обзоры на Apex Legends, однако, что бы я ни делал, я получаю 1427 обзоров. Я пробовал много вещей, таких как удаление языкового фильтра, изменение фильтра активности не по теме, создание динамической даты окончания, однако мне не удалось собрать все отзывы.
После курсора, который дает 27 отзывов (это первый раз, когда я получаю что-то кроме 100), следующий курсор — AoJwq+Kw1PUCf/CWrQI=, он дает 0 отзывов и также возвращается в качестве следующего курсора.
Мой код следующий, есть ли какие-нибудь предложения, чтобы я мог собрать все отзывы, заранее спасибо.
import requests
from datetime import datetime
import urllib.parse
import time
def fetch_game_reviews(appid, cursor='*', filter='recent', language='english'):
"""
Fetch game reviews for a specific Steam game.
Parameters:
- appid: Steam Application ID for the game.
- cursor: Cursor for pagination. Use '*' for the first page.
- filter: Type of reviews to fetch ('recent', 'updated', 'all').
- language: Language of the reviews ('english', 'spanish', etc.).
Returns:
- JSON response containing game reviews.
"""
if cursor != '*':
cursor = urllib.parse.quote(cursor)
url = f"https://store.steampowered.com/appreviews/{appid}?json=1&cursor = {cursor}&filter = {filter}&language = {language}&num_per_page=100&filter_offtopic_activity=0"
response = requests.get(url)
return response.json()
def fetch_reviews_until_date(appid, end_date, filter='recent', language='all'):
"""
Fetch game reviews for a specific Steam game until a specific date.
Parameters:
- appid: Steam Application ID for the game.
- end_date: The end date for fetching reviews (YYYY-MM-DD format).
- filter: Type of reviews to fetch ('recent', 'updated', 'all').
- language: Language of the reviews ('english', 'spanish', etc.).
Returns:
- List of all reviews up until the specified end date.
"""
end_date = datetime.strptime(end_date, '%Y-%m-%d')
previous_cursor = None
all_reviews = []
cursors = []
cursor = '*'
while True:
response = fetch_game_reviews(appid, cursor=cursor, filter=filter, language=language)
collected_timestamp = int(time.time())
reviews = response['reviews']
new_cursor = response.get('cursor')
cursors.append(new_cursor)
if not reviews or (new_cursor == previous_cursor and cursor != '*'):
return all_reviews, cursors
for review in reviews:
review_date = datetime.fromtimestamp(review['timestamp_created'])
review['collected'] = collected_timestamp
review['appid'] = appid
if review_date < end_date:
return all_reviews
all_reviews.append(review)
print(len(all_reviews))
print(response['cursor'])
previous_cursor = cursor
cursor = new_cursor
return all_reviews, cursors
reviews, cursors = fetch_reviews_until_date('1172470', '2020-10-01')
у вас неправильные отступы. У вас есть print()
внутри for
-цикла, поэтому он отображает одно и то же значение для каждого отзыва в списке. Вы должны отобразить его снаружи for
-цикла
В данном случае вы могли бы добавить ссылку на эту страницу в Steam - возможно, на ней всего 1427 отзывов.
Возможно, у Steam какие-то проблемы на сервере, и вам придется подождать, пока они это исправят. ИЛИ вы можете отправить эту информацию администраторам Steam.
В документации для getreviews показаны некоторые другие параметры — review_type
, purchase_type
, day_range
— и они отмечены как Required
.
Когда я добавляю эти параметры (кроме day_range
), код дает мне гораздо больше отзывов.
Я остановил код на 25 000
обзорах и не проверил окончательный номер.
payload = {
'json': 1,
'cursor': cursor,
'filter': filter,
'language': language,
'num_per_page': 100,
'filter_offtopic_activity': 0,
#'day_range': 365,
'review_type': 'all',
'purchase_type': 'all',
}
#print(payload)
url = f"https://store.steampowered.com/appreviews/{appid}"
response = requests.get(url, params=payload)
Полный рабочий код:
"""
# date: 2024.07.03
# [User Reviews - Get List (Steamworks Documentation)](https://partner.steamgames.com/doc/store/getreviews)
"""
import time
from datetime import datetime
import requests
def fetch_game_reviews(appid, cursor='*', filter='recent', language='english'):
"""
Fetch game reviews for a specific Steam game.
Parameters:
- appid: Steam Application ID for the game.
- cursor: Cursor for pagination. Use '*' for the first page.
- filter: Type of reviews to fetch ('recent', 'updated', 'all').
- language: Language of the reviews ('english', 'spanish', etc.).
Returns:
- JSON response containing game reviews.
"""
payload = {
'json': 1,
'cursor': cursor,
'filter': filter,
'language': language,
'num_per_page': 100,
'filter_offtopic_activity': 0,
#'day_range': 365,
'review_type': 'all',
'purchase_type': 'all',
}
#print('payload:', payload)
url = f"https://store.steampowered.com/appreviews/{appid}"
response = requests.get(url, params=payload)
#print('response.status_code:', response.status_code)
#print('response.text:', response.text)
return response.json()
def fetch_reviews_until_date(appid, end_date, filter='recent', language='all'):
"""
Fetch game reviews for a specific Steam game until a specific date.
Parameters:
- appid: Steam Application ID for the game.
- end_date: The end date for fetching reviews (YYYY-MM-DD format).
- filter: Type of reviews to fetch ('recent', 'updated', 'all').
- language: Language of the reviews ('english', 'spanish', etc.).
Returns:
- List of all reviews up until the specified end date.
"""
end_date = datetime.strptime(end_date, '%Y-%m-%d')
previous_cursor = None
all_reviews = []
cursors = []
cursor = '*'
while True:
response = fetch_game_reviews(appid, cursor=cursor, filter=filter, language=language)
collected_timestamp = int(time.time())
reviews = response['reviews']
new_cursor = response.get('cursor')
cursors.append(new_cursor)
if not reviews or (new_cursor == previous_cursor and cursor != '*'):
return all_reviews, cursors
for review in reviews:
review_date = datetime.fromtimestamp(review['timestamp_created'])
review['collected'] = collected_timestamp
review['appid'] = appid
if review_date < end_date:
return all_reviews
all_reviews.append(review)
# - after loop -
print('len:', len(all_reviews))
print('cursor:', response['cursor'])
previous_cursor = cursor
cursor = new_cursor
return all_reviews, cursors
reviews, cursors = fetch_reviews_until_date('1172470', '2020-10-01')
Большое спасибо за ваши комментарии и ваш ответ, я был очень взволнован, так как это первый раз, когда это не сработало должным образом, и, как вы заметили, я пропустил некоторую дополнительную информацию! Несмотря на то, что в моем вопросе не хватало информации, большое спасибо за подробный ответ, ваше время и интерес, все работает, как задумано!
Возможно, сначала используйте
print()
(иprint(type(...))
,print(len(...))
и т. д.), чтобы увидеть, какая часть кода выполняется и что на самом деле у вас есть в переменных. Он называется"print debugging"
и помогает увидеть, что на самом деле делает код.