Closed Matheuspimentell closed 2 years ago
Iniciamos a busca de dados da listagem do SIGAA. Até o momento, o código já é capaz de buscar, contar e imprimir todas as disciplinas disponíveis no departamento selecionado (FGA).
Abaixo, segue o código produzido até o momento.
import time
import requests
#import pandas as pd
#from bs4 import BeautifulSoup
from selenium import webdriver
from selenium.webdriver.firefox.options import Options
from webdriver_manager.firefox import GeckoDriverManager
#import json
url = "https://sig.unb.br/sigaa/public/turmas/listar.jsf?aba=p-ensino"
option = Options()
option.headless = True
driver = webdriver.Firefox(executable_path=GeckoDriverManager().install())
driver.get(url)
time.sleep(6)
#driver.find_element_by_xpath("//*[@id='formTurma:inputDepto']").click()
driver.find_element_by_id("formTurma:inputDepto").click()
driver.find_element_by_xpath('//*[@id="formTurma:inputDepto"]/option[79]').click()
driver.find_element_by_name('formTurma:j_id_jsp_1370969402_11').click()
contadorMaterias = 0
element = driver.find_elements_by_class_name('tituloDisciplina')
for k in element:
html_content = k.get_attribute('innerHTML')
print(html_content)
contadorMaterias += 1
print('Total de disciplinas apresentadas na listagem: ', contadorMaterias)
# element1 = driver.find_elements_by_class_name('linhaPar')
# element2 = driver.find_elements_by_class_name('linhaImpar')
# for k in element1:
# html_content = k.get_attribute('outerHTML')
# #print(html_content)
# i += 1
# for k in element2:
# html_content = k.get_attribute('outerHTML')
# #print(html_content)
# i += 1
driver.quit()
@AdneMoretti @gabrielm2q
As partes comentadas do código acima podem ser utilizadas futuramente para acessar todas as turmas e calcular o total de turmas do departamento.
# element1 = driver.find_elements_by_class_name('linhaPar')
# element2 = driver.find_elements_by_class_name('linhaImpar')
# for k in element1:
# html_content = k.get_attribute('outerHTML')
# #print(html_content)
# i += 1
# for k in element2:
# html_content = k.get_attribute('outerHTML')
# #print(html_content)
# i += 1
Para complementar o código produzido, estaremos elaborando um pequeno "tutorial" para a execução do código, mostrando quais tecnologias foram utilizadas e como realizar a instalação.
Além disso, é possível evoluir o código com a estruturação dos dados recebidos, de modo a produzir um arquivo Json com todos os dados retirados do site, de modo a facilitar a inserção no BD.
O seguinte vídeo possui explicações que podem ajudar no entendimento do Web Scraping utilizando o Selenium, BeautifulSoup e o Pandas. Vídeo: Python na Prática fazendo Web Scraping (de JavaScript dinâmico)
from selenium import webdriver
from selenium.webdriver.firefox.options import Options
from webdriver_manager.firefox import GeckoDriverManager
option = Options()
option.headless = True
driver = webdriver.Firefox(executable_path=GeckoDriverManager().install())
def acessarURL():
url = "https://sig.unb.br/sigaa/public/turmas/listar.jsf?aba=p-ensino"
driver.get(url)
def selecionarNivelEnsino():
botaoCampoEnsino = driver.find_element_by_id('formTurma:inputNivel')
botaoGraduacao = driver.find_element_by_xpath('//*[@id="formTurma:inputNivel"]/option[3]')
botaoCampoEnsino.click()
botaoGraduacao.click()
def selecionarUnidade():
botaoUnidade = driver.find_element_by_id('formTurma:inputDepto')
botaoFGA = driver.find_element_by_xpath('//*[@id="formTurma:inputDepto"]/option[79]')
botaoUnidade.click()
botaoFGA.click()
def acionarBotaoBuscar():
botaoBuscar = driver.find_element_by_name('formTurma:j_id_jsp_1370969402_11')
botaoBuscar.click()
def verificaVagas():
contadorDocentes = 0
contadorVagas = 0
element1 = driver.find_elements_by_xpath("//td[@style='text-align: center;']")
for x in element1:
resto = contadorVagas % 2
html_content = x.get_attribute('innerHTML')
if resto == 1:
disciplina = driver.find_elements_by_xpath("//td[@class='nome']")[contadorDocentes]
turma = disciplina.get_attribute('innerHTML')
print(f'Vagas em {turma}: {html_content}')
contadorDocentes += 1
contadorVagas += 1
return contadorVagas
def fecharJanela():
driver.quit()
def main():
acessarURL()
driver.implicitly_wait(6)
selecionarNivelEnsino()
selecionarUnidade()
acionarBotaoBuscar()
contadorVagas = verificaVagas()
print(f'Numero de Turmas encontradas: {contadorVagas/2}')
fecharJanela()
main()
Código formatado de uma forma diferente, porém com as mesmas lógicas e funcionalidades, diferença para auxiliar na leitura para quem não pode participar do desenvolvimento (funcionalidades separadas em funções e variáveis melhor descritas).
Na produção da primeira versão do código, foram usados os seguintes softwares:
Para a execução do projeto, é necessário instalar o Selenium. Para tal, utilize o seguinte comando no terminal (Ubuntu/Linux):
pip3 install selenium==4.1.0
Instale o webdriver manager:
pip3 install webdriver-manager==3.5.3
Para instalar o urllib3 na versão correta talvez seja necessário desinstalar a versão já existente. Para isso, use o comando no terminal:
pip3 uninstall urllib3
Então, instale o urllib3 com o seguinte comando:
pip3 install urllib3==1.21.1
Por fim, para verificar se as versões dos softwares instalados estão corretas, basta usar o seguinte comando e verificar a versão de cada um deles:
pip3 list
# Importando as bibliotecas e módulos necessários para a execução do scraping
import time
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.firefox.service import Service
from selenium.webdriver.firefox.options import Options
from webdriver_manager.firefox import GeckoDriverManager
# Armazenando a URL da página inicial da listagem do SIGAA
url = "https://sig.unb.br/sigaa/public/turmas/listar.jsf?aba=p-ensino"
# Configurando o driver do navegador e passando a URL do SIGAA para ele
option = Options()
option.headless = True
servicoFirefox = Service(GeckoDriverManager().install())
driver = webdriver.Firefox(service=servicoFirefox, options=option)
driver.get(url)
# Aqui temos uma pausa de 2 segundos para que o navegador carregue as
# informações necessárias antes de iniciar o scraping
time.sleep(2)
# Aqui estamos selecionando a opção "Graduação"
driver.find_element(By.ID, "formTurma:inputNivel").click()
driver.find_element(By.XPATH, '//*[@id="formTurma:inputNivel"]/option[3]').click()
# Aqui estamos selecionando o departamento "Faculdade do Gama"
driver.find_element(By.ID, "formTurma:inputDepto").click()
driver.find_element(By.XPATH, '//*[@id="formTurma:inputDepto"]/option[79]').click()
# Clicando no botão de busca
driver.find_element(By.NAME, 'formTurma:j_id_jsp_1370969402_11').click()
# Aqui temos uma pausa de 2 segundos para que o navegador carregue as
# informações necessárias antes de iniciar o scraping
time.sleep(2)
# contadorMaterias armazenará a quantidade de matérias contadas na lista
contadorMaterias = 0
# Aqui estamos importando uma lista com todos os títulos de matérias
# presentes na página do SIGAA
element = driver.find_elements(By.CLASS_NAME, 'tituloDisciplina')
# Vamos passar por todos os elementos (matérias) da lista de oferta
# para printar todas elas e contar a quantidade total de matérias
for k in element:
html_content = k.get_attribute('innerHTML')
print(html_content)
contadorMaterias += 1
print('Quantidade de matérias apresentadas na listagem: ', contadorMaterias)
# Encerrando o navegador
driver.quit()
Tutorial produzido por: @AdneMoretti @gabrielm2q
O código foi refatorado de forma a retirar quaisquer funcionalidades obsoletas (ou deprecated) e de modo a proporcionar uma melhor visualização do mesmo, comentando e separando as funcionalidades. Segue para revisão.
Seguindo o exemplo deixado pelo @oCaioOliveira, o código foi "refatorado" de modo a dividir todas as atividades em métodos e centralizar os passos da execução do código na "main()". Novamente, o código segue para revisão.
O código foi revisado e está coletando os dados normalmente, mas não está inicializando o firefox, para inicializá-lo basta retirar as linhas 13 e 14 e inserir o seguinte comando:
driver = webdriver.Firefox(executable_path=GeckoDriverManager().install())
O Firefox é iniciado no background devido ao parâmetro "options=option" passado para o driver do mesmo. Para exibir o navegador, basta retirar este parâmetro! Todavia, com ou sem a exibição do navegador, os dados são coletados e disponibilizados normalmente, conforme citado.
Abaixo, o trecho do código (linha 14) responsável por exibir ou ocultar o navegador:
driver = webdriver.Firefox(service=servicoFirefox, options=option)
Como foi passado que os dados estão sendo coletados normalmente, a issue será fechada.
Descrição
Realizar o scraping dos dados do SIGAA relacionados à quantidade de disciplinas ofertadas pelo departamento: FACULDADE DO GAMA - BRASÍLIA.
Tarefas
Critérios de aceitação