Я создал приложение с флягой, которое сможет сканировать некоторые данные.Первым шагом является использование API данных Youtube для получения некоторых данных о пользователе, включая список всех видео, которые пользователь когда-либо загружал.Это прекрасно работает!После того, как я получил список идентификаторов видео, я пытаюсь собрать все эти видео на YouTube, чтобы выделить лайки и просмотры по всем видео и собрать их вместе в 2 больших числа.Я проверял это локально без gunicorn и не в движке приложения, он работает отлично!Но когда пользователь загрузил 6700 видео, выполнение запроса может занять 30 минут (локально это работает). Когда я пытаюсь запустить тот же код в GAE, он возвращает 502 Bad Gateway через несколько минут, но в журналах я вижу, что он все еще ползает.Это GET 502:
Работник продолжал очищать в течение нескольких минут.
Вот код, который я написал для сканирования: Это мой app.yaml.С помощью -t 36000 рабочие могут молчать в течение одного часа, пока их не убьют и не перезапустят.
runtime: python37
service: crawler
entrypoint: . ./env.inc.sh && gunicorn -t 36000 -b :$PORT app:app
Это маршрут в моем app.py, который называется:
@app.route('/youtube/username/<user>')
def youtubeStatistics(user):
response = crawler.crawl_youtube_user(os.environ['YOUTUBE_API_KEY'], user)
if response:
return jsonify(response), 200
else:
return jsonify({"prettyMessage": "Quota Limit maybe Exceeded"}), 403
ЭтиИспользуются ли мои функции сканирования:
def scrape_url(url):
r = requests.get(url)
page = r.text
soup = bs(page, 'html.parser')
return soup
def crawl_youtube_user(KEY, username):
youtube = set_up(KEY)
request = youtube.channels().list(
part="snippet,contentDetails,statistics",
forUsername=username
)
uploadPlaylistId = ""
data = {}
try:
response = request.execute()
except:
return {}
if (response["pageInfo"]["totalResults"] > 0):
stats = response["items"][0]["statistics"]
data["subscriberCount"] = stats["subscriberCount"]
data["videoCount"] = stats["videoCount"]
data["publishedAt"] = response["items"][0]["snippet"]["publishedAt"]
uploadPlaylistId = response["items"][0]["contentDetails"]["relatedPlaylists"]["uploads"]
request = youtube.playlistItems().list(
part="snippet,contentDetails",
maxResults=50,
playlistId=uploadPlaylistId
)
videoIds = []
while True:
try:
response = request.execute()
except:
return {}
for vid in response["items"]:
videoIds.append(vid["snippet"]["resourceId"]["videoId"])
if "nextPageToken" not in response:
break
else:
request = youtube.playlistItems().list(
part="snippet,contentDetails",
maxResults=50,
playlistId=uploadPlaylistId,
pageToken=response["nextPageToken"]
)
data.update(crawl_youtube_videos(videoIds))
return data
def crawl_youtube_videos(ids):
data = {'viewCount': 0, 'videoLikes': 0}
counter = 0
idlength = len(ids)
for id in ids:
counter += 1
print('{}/{}: Scraping Youtube videoId {}'.format(counter,idlength,id))
soup = scrape_url('https://www.youtube.com/watch?v={}&gl=DE&hl=de'.format(id))
try:
data['viewCount'] += int(soup.find('div', class_='watch-view-count').getText().split(' ')[0].replace('.', '').replace(',', ''))
except:
print("Error while trying to extract the views of a Video: {}.".format(sys.exc_info()[0]))
try:
data['videoLikes'] += int(soup.find("button",{"title": "Mag ich"}).find("span").getText().replace('.', '').replace(',', ''))
except:
print("Error while trying to extract the likes of a Video: {}.".format(sys.exc_info()[0]))
return data
Я не хочу использовать больше потоков или что-то в этом роде, чтобы ускорить весь процесс!Я боюсь, что мой IP будет заблокирован или что-то в этом роде, если я заскочу на многие сайты за короткое время.Я просто пытаюсь сохранить запрос, пока не получу ответ, который хочу.Так есть ли еще механизмы, которые защищают приложение GAE от длительного времени отклика или что-то в этом роде? И как лучше всего реагировать на запросы, которые занимают 30-60 минут?