Visão Geral

A udemy-userAPI facilita o acesso programático a informações de cursos da Udemy, simulando o comportamento do navegador para aceder e renderizar os cursos. É ideal para utilizadores que desejam analisar os seus cursos inscritos, gerir recursos ou automatizar tarefas relacionadas com o conteúdo dos cursos.

Funcionalidades Principais

  • Autenticação na Udemy (via email/senha, cookies diretos ou login sem senha com OTP).
  • Listagem de todos os cursos nos quais o utilizador está inscrito.
  • Obtenção de detalhes abrangentes de um curso específico (título, instrutores, capítulos, aulas, quizzes, recursos adicionais).
  • Acesso a informações de aulas individuais, incluindo tipo de asset (vídeo, artigo, quiz), fontes de mídia, legendas, URLs de download e recursos.
  • Capacidade de lidar com conteúdo protegido por DRM, extraindo chaves de licença.

Arquitetura da Biblioteca

A biblioteca é modular. A classe principal `Udemy` serve como fachada, utilizando outros módulos para funcionalidades específicas como autenticação e obtenção de dados.

Udemy (Fachada)

Ponto de entrada principal

Authenticate

Gestão de Login

Sections

Obtenção de Cursos

API & Bultins

Funções Auxiliares e Modelos de Dados

Instalação

A udemy-userAPI pode ser instalada diretamente via pip. Certifique-se de que tem o Python e o pip instalados no seu sistema.

pip install udemy-userAPI

Uso Básico

Esta secção irá guiá-lo através das funcionalidades essenciais da udemy-userAPI, desde a autenticação segura na sua conta Udemy até à exploração detalhada dos seus cursos e aulas. Cada passo é explicado de forma clara e com exemplos práticos para que possa começar a utilizar a biblioteca sem dificuldades.

1. Como Autenticar-se na Udemy

Para aceder aos seus cursos e dados na Udemy, a biblioteca precisa de se autenticar na sua conta. A classe UdemyAuth é a sua ferramenta para gerir este processo de forma segura e flexível. É uma boa prática verificar sempre se já está logado para evitar tentativas de login desnecessárias.

Login com Email e Senha (Método Padrão)

Este é o método mais comum. A biblioteca simula o processo de login do navegador. Lembre-se de que as suas credenciais são sensíveis e devem ser tratadas com segurança (evite colocá-las diretamente no código para produção).

from udemy_userAPI import UdemyAuth, LoginException

auth = UdemyAuth()
try:
    if not auth.verif_login():
        print("Sessão não encontrada ou expirada. A iniciar sessão...")
        email_udemy = input("Digite seu e-mail da Udemy: ")
        senha_udemy = input("Digite sua senha da Udemy: ")
        auth.login(email_udemy, senha_udemy)
        print("Login bem-sucedido! Seus cookies de sessão foram salvos.")
    else:
        print("Já está logado! Sessão válida encontrada.")
except LoginException as e:
    print(f"Erro de login: {e}")
except Exception as e:
    print(f"Ocorreu um erro inesperado durante a autenticação: {e}")

Login com Autenticação de Dois Fatores (2FA/Passwordless)

Se a sua conta Udemy tem 2FA ativado (login sem senha), pode usar este método. A biblioteca irá enviar um código para o seu email e pedir que o insira para completar o login.

from udemy_userAPI import UdemyAuth, LoginException

auth_2fa = UdemyAuth()

def obter_otp_do_usuario():
    """Função de callback para obter o OTP do usuário."""
    return input("Digite o código de 6 dígitos enviado ao seu e-mail: ")

try:
    if not auth_2fa.verif_login():
        print("Sessão não encontrada ou expirada. Iniciando login sem senha...")
        email_udemy_2fa = input("Digite seu e-mail da Udemy para 2FA: ")
        auth_2fa.login_passwordless(email_udemy_2fa, otp_callback=obter_otp_do_usuario)
        print("Login sem senha bem-sucedido!")
    else:
        print("Já está logado! Sessão válida encontrada.")
except LoginException as e:
    print(f"Erro de login 2FA: {e}")
except Exception as e:
    print(f"Ocorreu um erro inesperado durante a autenticação 2FA: {e}")

Gestão de Cookies (Avançado)

Se já tem cookies de sessão da Udemy (por exemplo, extraídos do seu navegador), pode usá-los diretamente para autenticação. A biblioteca também permite remover os cookies guardados.

from udemy_userAPI import UdemyAuth, LoginException
import os

auth_cookies = UdemyAuth()

# Exemplo: Login direto com uma string de cookies
# Lembre-se de que esta string deve ser obtida de uma sessão válida do navegador.
sua_string_de_cookies = "client_id=...; access_token=...;" # Substitua pelos seus cookies reais
try:
    auth_cookies.login_direct_cookies(sua_string_de_cookies)
    print("Login com cookies diretos bem-sucedido!")
except LoginException as e:
    print(f"Erro ao tentar login com cookies diretos: {e}")

# Carregar cookies salvos (se existir uma sessão salva)
loaded_cookies = auth_cookies.load_cookies()
print(f"Cookies carregados: {loaded_cookies[:50]}...") # Mostra apenas o início

# Remover cookies salvos de uma sessão (para logout ou nova sessão)
# auth_cookies.remove_cookies()
# print("Cookies de sessão removidos.")

Para se obter os cookies você pode utilizar as opções de desenvolvedor no navedaor -> (f12) -> rede -> filtre por https://www.udemy.com/api-2.0/ ->só copiar os cookies de uma requisição.

2. Como Obter a Lista dos Seus Cursos

Depois de se autenticar com sucesso, o próximo passo é aceder à lista dos cursos nos quais está inscrito. A classe Udemy é a sua porta de entrada para todas as informações sobre os cursos.

Listar Todos os Seus Cursos Inscritos

O método my_subscribed_courses() irá buscar todos os cursos que aparecem na sua página "Meus Cursos" na Udemy, sejam eles comprados individualmente ou parte de um plano de assinatura.

from udemy_userAPI import Udemy

# Certifique-se de que já fez o login antes de usar a classe Udemy
udemy = Udemy()
try:
    todos_os_cursos = udemy.my_subscribed_courses()
    print(f"Você tem {len(todos_os_cursos)} cursos inscritos no total.")
    
    if todos_os_cursos:
        print("\nInformações dos primeiros 3 cursos:")
        for i, curso in enumerate(todos_os_cursos[:3]):
            print(f"- Título: {curso.get('title')}")
            print(f"  ID do Curso: {curso.get('id')}")
            print(f"  Percentual de Conclusão: {curso.get('completion_ratio', 0) * 100:.2f}%")
except Exception as e:
    print(f"Ocorreu um erro ao listar seus cursos: {e}")

**Dica:** Se você possui uma assinatura (Personal Plan) e deseja ver apenas os cursos incluídos nela, use udemy.my_subscribed_courses_by_plan().

3. Como Obter Detalhes Completos de um Curso

A lista de cursos que obteve anteriormente fornece informações básicas. Para mergulhar fundo e ver todos os capítulos, aulas, instrutores, recursos e muito mais de um curso específico, precisa de obter os seus detalhes completos. Para isso, usará o ID do curso.

Aceder a Informações Detalhadas do Curso

O método estático Udemy.get_details_course(ID_DO_CURSO) retorna um objeto Course. Este objeto é uma representação rica do curso, permitindo-lhe aceder a diversas propriedades como título, descrição, lista de instrutores, número de aulas, e muito mais.

from udemy_userAPI import Udemy

# Substitua este ID pelo ID de um dos seus cursos (obtido do passo anterior)
id_do_curso_exemplo = 123456 

try:
    detalhes_do_curso = Udemy.get_details_course(id_do_curso_exemplo)
    
    print(f"\n--- Detalhes do Curso: {detalhes_do_curso.title_course} ---")
    print(f"Descrição (início): {detalhes_do_curso.description_course[:150]}...")
    print(f"Categoria Principal: {detalhes_do_curso.primary_category}")
    print(f"Duração Estimada (minutos): {detalhes_do_curso.estimated_content_length}")
    print(f"Número total de Aulas: {detalhes_do_curso.count_lectures}")
    print(f"Número total de Capítulos: {detalhes_do_curso.count_chapters}")
    
    # Informações sobre os Instrutores
    if detalhes_do_curso.instructors:
        print("\nInstrutores:")
        for instrutor in detalhes_do_curso.instructors:
            print(f"- {instrutor.get('display_name')} ({instrutor.get('job_title')})")

    # Exemplo de como aceder à lista de aulas (resumo)
    if detalhes_do_curso.get_lectures:
        print(f"\nPrimeiras 5 aulas (resumo):")
        for i, aula_resumo in enumerate(detalhes_do_curso.get_lectures[:5]):
            print(f"  - Capítulo {aula_resumo.get('section')}: {aula_resumo.get('title')} (ID: {aula_resumo.get('lecture_id')}, Tipo: {aula_resumo.get('asset_type')})")

except Exception as e:
    print(f"Ocorreu um erro ao obter detalhes do curso {id_do_curso_exemplo}: {e}")

4. Como Obter Aulas e Seus Detalhes Específicos

Um curso é composto por várias aulas, e cada aula pode ser um vídeo, um artigo, um quiz, etc. A udemy-userAPI permite-lhe listar todas as aulas de um curso e, mais importante, obter detalhes muito específicos de cada uma delas, como o conteúdo do vídeo, o texto de um artigo, ou as perguntas de um quiz.

Listar Aulas de um Curso

Depois de ter o objeto Course (do passo anterior), pode aceder à propriedade get_lectures para obter uma lista de todos os resumos das aulas. Esta lista é útil para ter uma visão geral e encontrar o ID da aula que deseja explorar em detalhe.

from udemy_userAPI import Udemy

id_do_curso_para_aulas = 123456 # Substitua pelo ID de um dos seus cursos

try:
    detalhes_do_curso_aulas = Udemy.get_details_course(id_do_curso_para_aulas)
    
    if detalhes_do_curso_aulas.get_lectures:
        print(f"\nListando todas as aulas do curso '{detalhes_do_curso_aulas.title_course}':")
        for aula_resumo in detalhes_do_curso_aulas.get_lectures:
            print(f"- Capítulo: {aula_resumo.get('section')}, Título: {aula_resumo.get('title')} (ID: {aula_resumo.get('lecture_id')}, Tipo: {aula_resumo.get('asset_type')})")
    else:
        print("Nenhuma aula encontrada para este curso.")

except Exception as e:
    print(f"Ocorreu um erro ao listar as aulas: {e}")

Obter Detalhes de uma Aula Específica

Com o ID de uma aula (obtido do passo anterior), pode usar o método get_details_lecture(ID_DA_AULA) do seu objeto Course para obter um objeto Lecture. Este objeto contém todas as informações disponíveis para aquela aula específica, adaptadas ao seu tipo (vídeo, artigo, quiz).

from udemy_userAPI import Udemy

id_do_curso_aula_detalhe = 123456 # Substitua pelo ID do curso da aula
id_da_aula_exemplo = 789012 # Substitua pelo ID da aula que deseja detalhar

try:
    detalhes_do_curso_parent = Udemy.get_details_course(id_do_curso_aula_detalhe)
    aula_detalhada = detalhes_do_curso_parent.get_details_lecture(id_da_aula_exemplo)
    
    print(f"\n--- Detalhes da Aula: {aula_detalhada.get_description[:100]}... ---")
    print(f"ID da Aula: {aula_detalhada.get_lecture_id}")
    print(f"Tipo de Conteúdo: {aula_detalhada.get_asset_type}")
    print(f"É uma aula gratuita? {'Sim' if aula_detalhada.is_free else 'Não'}")

    if aula_detalhada.get_asset_type.lower() == 'video':
        print("\nDetalhes do Vídeo:")
        print(f"Token de Licença de Mídia: {aula_detalhada.get_media_license_token}")
        if aula_detalhada.get_media_sources:
            print(f"  Fontes de vídeo disponíveis: {len(aula_detalhada.get_media_sources)} opções.")
            print(f"  Exemplo de URL de vídeo: {aula_detalhada.get_media_sources[0].get('src')[:80]}...")
        if aula_detalhada.get_captions:
            print(f"  Legendas disponíveis para os idiomas: {aula_detalhada.get_captions.languages()}")
            # Para obter o conteúdo de uma legenda específica:
            # pt_caption_content = aula_detalhada.get_captions.get_lang('pt').content
            # print(f"  Conteúdo da legenda em PT (início): {pt_caption_content[:100]}...")
        if aula_detalhada.course_is_drmed():
            print("  Esta aula é protegida por DRM. Chaves de licença podem ser extraídas.")

    elif aula_detalhada.get_asset_type.lower() == 'article':
        print("\nDetalhes do Artigo:")
        conteudo_do_artigo = aula_detalhada.get_articles
        print(f"  Conteúdo (HTML, início): {conteudo_do_artigo[:200]}...")

    elif aula_detalhada.get_asset_type.lower() == 'quiz':
        print("\nDetalhes do Quiz:")
        objeto_quiz = aula_detalhada.quiz_object()
        print(f"  Título do Quiz: {objeto_quiz.title}")
        print(f"  Descrição: {objeto_quiz.description}")
        print(f"  Número de Perguntas: {objeto_quiz.num_assessments}")
        print(f"  Percentual para Aprovação: {objeto_quiz.pass_percent}%")
        # O conteúdo das perguntas pode ser acedido via objeto_quiz.content()

    if aula_detalhada.get_resources:
        print("\nRecursos Adicionais (Ficheiros para Download):")
        for recurso in aula_detalhada.get_resources:
            print(f"- Título: {recurso.get('title-file')}, Link Externo: {recurso.get('external_link')}")

except Exception as e:
    print(f"Ocorreu um erro ao explorar a aula {id_da_aula_exemplo}: {e}")

Módulo: udemy.py

O ponto de entrada principal da biblioteca.

Classe Udemy

Wrapper para API de utilizador da plataforma Udemy.

class Udemy:
    def __init__(self):
        """
        Inicializa o objeto Udemy.
        Raises: LoginException: Se a sessão estiver expirada.
        """

Métodos Estáticos

my_subscribed_courses_by_plan() -> list[dict]: Obtém os cursos inscritos através de planos (assinatura).

my_subscribed_courses() -> list[dict]: Obtém todos os cursos inscritos (padrão e de planos).

get_details_course(course_id: int) -> Course: Obtém detalhes de um curso através do ID.

Módulo: authenticate.py

Responsável pela gestão de sessões e autenticação do utilizador.

Classe UdemyAuth

Autenticação na plataforma Udemy de maneira segura.

verif_login() -> bool: Verifica se o utilizador está logado.

login(email, password, locale='pt_BR'): Efetua login com email e senha.

login_direct_cookies(cookies): Efetua login usando uma string ou ficheiro de cookies.

load_cookies() -> str: Carrega cookies e retorna-os como string.

remove_cookies(): Remove o ficheiro de cookies de sessão.

login_passwordless(email, locale='pt_BR', otp_callback=None): Realiza login usando autenticação de dois fatores (2FA).

Módulo: sections.py

Contém funções para obter listas e detalhes de cursos.

Funções

get_courses_plan(tipe: str) -> list: Obtém uma lista de cursos com base no tipo de plano ('default' ou 'plan').

get_details_courses(course_id: int) -> dict: Obtém detalhes de um curso, com paginação automática.

get_course_infor(course_id: int) -> dict: Obtém informações gerais de um curso.

Módulo: api.py

Funções de baixo nível para interagir com a API da Udemy, incluindo DRM e processamento de dados.

Funções Notáveis

get_pssh(init_url) e extract(pssh, token): Funções para lidar com conteúdo protegido por DRM (Widevine).

get_mpd_file(mpd_url): Obtém e processa manifestos MPEG-DASH.

parser_chapters(results): Estrutura os dados do currículo em capítulos e aulas.

get_links(course_id, lecture_id): Obtém dados de uma aula específica (vídeo/artigo).

get_assessments(course_id, lecture_id): Obtém dados de um quiz.

Módulo: bultins.py

Define as classes de modelo de dados que representam as entidades da Udemy.

Classe Course

Representa um curso completo, com acesso a título, instrutores, aulas, etc.

Classe Lecture

Representa uma aula individual, com acesso a descrição, tipo de asset, recursos, etc.

Classe Quiz

Representa um quiz, com acesso a título, descrição e conteúdo.

Classes Caption(s)

Gerem as legendas de uma aula, permitindo listar idiomas e obter o conteúdo.

Classe DRM

Lida com a extração de chaves de licença para conteúdo protegido.

Classe Files

Gere os ficheiros para download associados a uma aula.

Módulo: exeptions.py

Define as exceções personalizadas para um tratamento de erros claro e específico.

Exceções

  • UdemyUserApiExceptions: Erro genérico da biblioteca.
  • Upstreamconnecterror: Falha de conexão com o servidor da Udemy.
  • UnhandledExceptions: Erros não tratados.
  • LoginException: Erros específicos do processo de login.

Changelog

Versão 0.3.11

  • Lançamento inicial da documentação para PyPI.

Licença

Esta biblioteca está licenciada sob a licença MIT. Consulte o ficheiro LICENSE no repositório para mais detalhes.