Ich habe versucht, die youtube Data API V3 im Scraping Primer zu verwenden. Ich stecke auf verschiedene Weise fest, also werde ich eine Spur hinterlassen.
youtube_api_metadata.py
import os
import logging
import csv
from apiclient.discovery import build
from pymongo import MongoClient, ReplaceOne, DESCENDING
from typing import Iterator, List
from pymongo.collection import Collection
YOUTUBE_API_KEY=os.environ['YOUTUBE_API_KEY']
logging.getLogger('googleapiclient.discovery_cache').setLevel(logging.ERROR)
def main():
mongo_client = MongoClient('localhost', 27017)
collections = mongo_client.youtube.videos
query = input('Bitte geben Sie den Suchwert an.:')
for items_per_page in search_videos(query):
save_to_momgo(collections, items_per_page)
save_to_csv(collections)
def search_videos(query: str, max_pages: int=5):
youtube = build('youtube', 'v3', developerKey=YOUTUBE_API_KEY)
search_request = youtube.search().list(
part='id',
q=query,
type='video',
maxResults=15,
)
i = 0
while search_request and i < max_pages:
search_response = search_request.execute()
video_ids = [item['id']['videoId'] for item in search_response['items']]
video_response = youtube.videos().list(
part='snippet,statistics',
id=','.join(video_ids),
).execute()
yield video_response['items']
search_requst = youtube.search().list_next(search_request, search_response)
i += 1
def save_to_momgo(collection: Collection, items: List[dict]):
for item in items:
item['_id'] = item['id']
for key, value in item['statistics'].items():
item['statistics'][key] = int(value)
operation = [ReplaceOne({'_id': item['_id']}, item, upsert=True) for item in items]
result = collection.bulk_write(operation)
logging.info(f'Upserted {result.upserted_count} documents.')
def save_to_csv(collection: Collection):
with open('top_videos_list.csv', 'w',newline='', encoding='utf-8-sig') as f:
writer = csv.DictWriter(f, ['title', 'viewCount'])
writer.writeheader()
for item in collection.find().sort('statistics.viewCount', DESCENDING):
writer.writerows([{'title' : item['snippet']['title'], 'viewCount': item['statistics']['viewCount']}])
if __name__ == '__main__':
logging.basicConfig(level=logging.INFO)
main()
Nach dem Implementieren und mehrmaligen Ausführen des Codes tritt der folgende Fehler auf.
sample.py
googleapiclient.errors.HttpError: <HttpError 403 when requesting https://www.googleapis.com/youtube/v3/videos?part=snippet%2Cstatistics&id=wXeR58bjCak%2CujxXyCrDnU0%2CQhhUVI0sxCc%2CKZz-7KSMjZA%2CWq-WeVQoE6U%2CG-qWwfG9mBE%2CYqUwEPSZQGQ%2CIuopzT_TWPQ%2CmcFspy1WhL8%2Ck9dcl7F6IFY%2C--Z5cvZ4JEw%2C3hidJgc9Zyw%2CdYSmEkcM_8s%2Ch6Hc4RuK8D8%2CRQfN2re3u4w&key=<YOUTUBE_API_KEY>&alt=json returned "The request cannot be completed because you have exceeded your <a href="/youtube/v3/getting-started#quota">quota</a>.">
Zuerst war ich mir nicht sicher, also suchte ich nach der Ursache.
Infolgedessen scheint die Ursache lediglich die Beschränkung der Verwendung von "Quoten" gewesen zu sein. Erstellen Sie ein neues Projekt aus GCP und geben Sie auf der Registerkarte Authentifizierung einen neuen API-Schlüssel aus. Setzen Sie den Schlüssel auf die unten stehende Umgebungsvariable und führen Sie die Python-Datei erneut aus.
set YOUTUBE_API_KEY=<YOUTUBE_API_KEY>
Infolgedessen wurde es ohne Probleme ausgeführt und eine CSV-Datei ausgegeben.
(scraping3.7) C:\Users\user\scraping3.7\files>python save_youtube_videos_matadata.py
Bitte geben Sie den Suchwert an.:Hikakin
INFO:root:Upserted 15 documents.
INFO:root:Upserted 0 documents.
INFO:root:Upserted 0 documents.
INFO:root:Upserted 0 documents.
INFO:root:Upserted 0 documents.
Von dem obigen Code sind die folgenden nicht sehr klar. Ich konnte nicht anders, als die Entwicklung zu stoppen.
operation = [ReplaceOne({'_id': item['_id']}, item, upsert=True) for item in items]
Als Ergebnis offizieller Untersuchungen wurde festgestellt, dass das Argument im folgenden Format eingeht. Offiziell
ReplaceOne(filter, replacement, options)
In den folgenden Fällen
ReplaceOne({'city': 'Tokio'}, {'city':'Gunma'}, upsert=True)
Wenn Daten von 'Stadt': 'Tokio' vorhanden sind, aktualisieren Sie auf Stadt ':' Gunma '. Wenn 'Stadt': 'Tokio' nicht existiert, fügen Sie eine neue 'Stadt' ein: 'Gunma'.
Recommended Posts