Python na prática: Projeto Video Creator – #Parte 3: Buscando o assunto escolhido na Wikipedia

Bom dia, boa tarde, boa noite!

Essa é a terceira parte da série sobre o projeto Video Creator, onde mostrarei a escolha pelo assunto, e a busca na Wikipedia.

Se você entrou direto nesse post, te aconselho a começar por aqui, para entender exatamente do que se trata essa série.

Sobre essa parte

Para essa versão inicial do projeto, segui a idéia do projeto original e minha fonte de dados textuais será apenas o Wikipedia. Mas já tenho algumas idéias pra evolução desse projeto :D.

Requisitos:

O consumo da API da Wikipedia também é bastante simples, precisei apenas da lib requests:

import requests

A URL que iremos consumir é a seguinte:

https://{language}.wikipedia.org/w/api.php?action=query&format=json&prop=extracts&exintro=1&exlimit=1&titles={subject}&explaintext=1&formatversion=2

Onde {language} é o idioma, neste caso coloquei como uma variável, pois é possível trocar e escolher outros idiomas. E {subject} é o assunto que iremos pesquisar.

A function que busca o conteúdo na wikipedia ficou assim:

def get_wikipedia_content(subject, lang):
    logging.info("Searching about the content choosen on wikipedia")
    print("")
    print("---------------------------------------------------------------------------------------------")
    print("Buscando conteúdo na wikipedia para assunto escolhido: {}".format(subject), end="\n\n")
    try:
        # main subject
        #url = "https://{}.wikipedia.org/api/rest_v1/page/summary/{}".format(lang, subject)
        main_url = WIKIPEDIA_MAIN_URL.format(lang, urllib.parse.unquote(subject))
        main_content = requests.get(main_url)
        main_content_json = main_content.json()
        main_result = main_content_json['query']['pages'][0]
        if  'missing' in main_content_json:
            return main_content_json['missing']
        # media
        media_url = "https://{}.wikipedia.org/api/rest_v1/page/media-list/{}?redirect=false".format(lang, subject)
        media_content = requests.get(media_url)
        media_content_json = media_content.json()
        # get images if there is
        if 'items' in media_content_json:
            media_result = media_content_json['items']
            # incluindo imagens no payload principal
            main_result['images'] = media_result
        # removing unnecessary keys
        main_result.pop('pageid', None)
        main_result.pop('ns', None)

        if 'extract' in main_result:
            return main_result['extract']
        else:
            raise ValueError("Conteúdo não encontrado")

    except Exception as ex:
        logging.error(ex)
        print(ex)

Mas como ocorre a escolha do assunto?

Para selecionar um assunto e chamar a function que buscará o conteúdo na wikipedia, eu encapsulei todo esse fluxo dentro de uma function chamada ask_for_a_subject(), que é responsável por buscar os trending topics do Google e do Twitter, mostrar no terminal o primeiro colocado de cada um e ainda uma terceira opção caso eu deseje digitar um assunto.

Abaixo segue como ficou a função:

def ask_for_a_subject():
    try:
        print("Getting google Trends...")
        gsubject = get_google_trends()
        print("Getting Twitter Trends...", end="\n\n")
        tsubject = get_twitter_trends()

        options = {}
        options[1] = gsubject[0]['title']
        options[2] = tsubject[0]['name']
        options[3] = "Outro"

        # log
        logging.info("--- Asking for content ---")
        # define variable
        content_choosen = "Nenhuma opção escolhida"
        print("Escolha uma das opções", end="\n\n")
        for k in options:
            print("{}) {}".format(k, options[k]))
        
        while content_choosen not in options:
            user_input = int(input("Digite o numero do conteúdo desejado: "))
            if user_input in options:
                content_choosen = options[int(user_input)]
                if content_choosen == 'Outro':
                    content_choosen = input("Digite um termo para ser pesquisado: ")
                    break    
                break
            else:
                print("Escolha uma opção válida")
    except Exception as ex:
        return ex

    return str(content_choosen)

Após a escolha do assunto, é solicitado a escolha da categoria desse conteúdo. Essa categoria será usada no upload do video.

A lista de categorias disponíveis coloquei fixo mesmo, dentro do arquivo rconfig.py. Ficou assim:

# FOR YOUTUBE
YOUTUBE_CATEGORY_LIST = [
        (1, 'Film & Animation'),
        (2, 'Autos & Vehicles'),
        (10, 'Music'),
        (15, 'Pets & Animals'),
        (17, 'Sports'),
        (18, 'Short Movies'),
        (19, 'Travel & Events'),
        (20, 'Gaming'),
        (21, 'Videoblogging'),
        (22, 'People & Blogs'),
        (23, 'Comedy'),
        (24, 'Entertainment'),
        (25, 'News & Politics'),
        (26, 'Howto & Style'),
        (27, 'Education'),
        (28, 'Science & Technology'),
        (29, 'Nonprofits & Activism'),
        (30, 'Movies'),
        (31, 'Anime/Animation'),
        (32, 'Action/Adventure'),
        (33, 'Classics'),
        (34, 'Comedy'),
        (35, 'Documentary'),
        (36, 'Drama'),
        (37, 'Family'),
        (38, 'Foreign'),
        (39, 'Horror'),
        (40, 'Sci-Fi/Fantasy'),
        (41, 'Thriller'),
        (42, 'Shorts'),
        (43, 'Shows'),
        (44, 'Trailers')
    ]

A função ficou assim:

def ask_for_a_category():
    # log
    logging.info("--- Asking for a category ---")
    print("Qual a categoria do conteúdo? ", end="\n\n")

    category_choosen = 0
    available_options = []
    for category in YOUTUBE_CATEGORY_LIST:
        print("{}) {}".format(category[0], category[1]))
        available_options.append(category[0])
    
    while category_choosen == 0:
        user_input = int(input("Digite o numero da categoria escolhida: "))
        if user_input in available_options:
            category_choosen = user_input
            break
        else:
            print("Escolha uma opção válida")

    return str(category_choosen)

Uma coisa importante, é que o id da categoria apesar de ser um numero inteiro, na API do Youtube, o atributo category_id espera receber uma string.

Após a escolha da categoria, a função get_wikipedia_content() é invocada passando o assunto escolhido e o idioma:


def get_wikipedia_content(subject, lang):
    logging.info("Searching about the content choosen on wikipedia")
    print("")
    print("---------------------------------------------------------------------------------------------")
    print("Buscando conteúdo na wikipedia para assunto escolhido: {}".format(subject), end="\n\n")
    try:
        # main subject
        #url = "https://{}.wikipedia.org/api/rest_v1/page/summary/{}".format(lang, subject)
        main_url = WIKIPEDIA_MAIN_URL.format(lang, urllib.parse.unquote(subject))
        main_content = requests.get(main_url)
        main_content_json = main_content.json()
        main_result = main_content_json['query']['pages'][0]
        if  'missing' in main_content_json:
            return main_content_json['missing']
        # media
        media_url = "https://{}.wikipedia.org/api/rest_v1/page/media-list/{}?redirect=false".format(lang, subject)
        media_content = requests.get(media_url)
        media_content_json = media_content.json()
        # get images if there is
        if 'items' in media_content_json:
            media_result = media_content_json['items']
            # incluindo imagens no payload principal
            main_result['images'] = media_result
        # removing unnecessary keys
        main_result.pop('pageid', None)
        main_result.pop('ns', None)

        if 'extract' in main_result:
            return main_result['extract']
        else:
            raise ValueError("Conteúdo não encontrado")

    except Exception as ex:
        logging.error(ex)
        print(ex)

No próximo post, mostrarei como fiz para a limpeza e interpretação do texto.

Um abraço e até o próximo post!