Created
July 6, 2014 19:12
-
-
Save ranisalt/8a125eb62fac0d61ca07 to your computer and use it in GitHub Desktop.
crawler
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env php | |
<?php | |
require 'simple_html_dom.php'; | |
$ch = curl_init(); | |
curl_setopt($ch, CURLOPT_COOKIEJAR, 'cookie.txt'); | |
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); | |
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); | |
/** | |
* Configurando URL, cookie e retorno da transferência | |
*/ | |
curl_setopt($ch, CURLOPT_URL, 'https://sistemas.ufsc.br/login'); | |
$get_login = trim(curl_exec($ch)); | |
if (!$get_login) { | |
exit('Erro ao acessar página de login: ' . curl_error($ch)); | |
} | |
echo 'Página de login acessada com sucesso', PHP_EOL; | |
/** | |
* Pegar o token da página usando simple html dom | |
*/ | |
$token = str_get_html(file_get_html('https://sistemas.ufsc.br/login'))->find('input[name="lt"]')[0]->value; | |
/** | |
* Construção | |
*/ | |
$post_login_fields = http_build_query(array( | |
'userType' => 'alunoGraduacao', | |
'username' => 'username', | |
'admin' => '0', | |
'password' => 'password', | |
'lt' => $token, | |
'_eventId' => 'submit', | |
)); | |
/** | |
* Configurando o POST para fazer login | |
*/ | |
curl_setopt($ch, CURLOPT_POST, true); | |
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_login_fields); | |
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/x-www-form-urlencoded')); | |
/** | |
* Executando login | |
*/ | |
$post_login = curl_exec($ch); | |
if (strpos($post_login, 'Sucesso ao se logar') === FALSE) | |
exit('Erro ao fazer login!'); | |
echo 'Login efetuado com sucesso!', PHP_EOL; | |
/** | |
* Limpando o cURL para o próximo request | |
*/ | |
curl_setopt($ch, CURLOPT_POSTFIELDS, null ); | |
curl_setopt($ch, CURLOPT_HTTPHEADER, array()); | |
/** | |
* Configurando o GET para a página de turmas | |
*/ | |
curl_setopt($ch, CURLOPT_POST, false ); | |
curl_setopt($ch, CURLOPT_URL, 'https://cagr.sistemas.ufsc.br/modules/aluno/cadastroTurmas/' ); | |
$get_cadastro_turmas = trim(curl_exec($ch)); | |
if (strpos($get_cadastro_turmas, 'Cadastro de Turmas') === FALSE) | |
exit('Erro ao acessar cadastro de turmas: ' . curl_error($ch)); | |
echo 'Cadastro de turmas acessado com sucesso', PHP_EOL; | |
$dom = str_get_html(utf8_encode($get_cadastro_turmas)); | |
$view_state = $dom->find('input[name="javax.faces.ViewState"]')[0]->value; | |
$post_turmas_fields = array( | |
'AJAXREQUEST' => '_viewRoot', | |
'formBusca:selectSemestre' => $dom->find('select[id="formBusca:selectSemestre"] option[selected="selected"]')[0]->value, | |
'formBusca:selectDepartamento' => '', | |
'formBusca:selectCampus' => '0', | |
'formBusca:selectCursosGraduacao' => '0', | |
'formBusca:codigoDisciplina' => '', | |
'formBusca:j_id136_selection' => '', | |
'formBusca:filterDisciplina' => '', | |
'formBusca:j_id140' => '', | |
'formBusca:j_id144_selection' => '', | |
'formBusca:filterProfessor' => '', | |
'formBusca:selectDiaSemana' => '0', | |
'formBusca:selectHorarioSemana' => '', | |
'formBusca' => 'formBusca', | |
'autoScroll' => '', | |
'javax.faces.ViewState' => $view_state, | |
'formBusca:dataScroller1' => '1', | |
'AJAX:EVENTS_COUNT' => '1', | |
); | |
curl_setopt($ch, CURLOPT_POST, true ); | |
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/x-www-form-urlencoded')); | |
function request_next_page(&$ch, &$dom, &$fields) { | |
/** | |
* Para incrementar a página, precisamos aumentar o valor da pesquisa | |
*/ | |
++$fields['formBusca:dataScroller1']; | |
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($fields)); | |
$dom = str_get_html(trim(curl_exec($ch))); | |
} | |
function request_next_campus(&$ch, &$dom, &$fields) { | |
/** | |
* Para requisitar o próximo campus, precisamos retornar à página 1 e incrementar o campus | |
*/ | |
$fields['formBusca:dataScroller1'] = 1; | |
++$fields['formBusca:selectCampus']; | |
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($fields)); | |
$dom = str_get_html(trim(curl_exec($ch))); | |
} | |
function parse_ufsc_xhtml($dom, &$dados) { | |
/** | |
* Procurar todas as linhas da tabela de horários da página atual ($dom) | |
*/ | |
$search = $dom->find('table[id="formBusca:dataTable"] > tbody[id="formBusca:dataTable:tb"] > tr'); | |
/** | |
* A primeira linha é o cabeçalho, porque o Simple HTML DOM é bugado | |
*/ | |
array_shift($search); | |
/** | |
* Iterar sobre todas as linhas da pesquisa | |
*/ | |
foreach($search as $key) { | |
$valor = $key->find('td'); | |
$id = trim($valor[3]->plaintext); | |
/** | |
* No caso de ser uma disciplina nova, precisa inicializar o nome, as turmas e horas-aula. | |
* Caso contrário é só adicionar. | |
*/ | |
if (empty($dados[$id])) { | |
$dados[$id] = array( | |
// Turmas | |
't' => array(), | |
// Nome | |
'n' => html_entity_decode(trim($valor[5]->plaintext)), | |
// Horas-aula | |
'h' => (int)rtrim($valor[6]->plaintext), | |
); | |
} | |
/** | |
* Explode o campo de horário + sala em: | |
* [1] => dia | |
* [2] => hora | |
* [3] => aulas em sequência | |
* [4] => sala | |
*/ | |
preg_match_all('/(\d)\.(\d{4})\-(\d)\s*\/\s*(\w{3}\-\w{6})/', $valor[12]->plaintext, $horario); | |
$horarios = array(); | |
for($j = 0, $max = count($horario[0]); $j < $max; ++$j) | |
$horarios[] = array( | |
// Dia | |
'd' => $horario[1][$j], | |
// Horário | |
'h' => $horario[2][$j], | |
// Aulas em sequência | |
'a' => $horario[3][$j], | |
// Sala | |
's' => $horario[4][$j] | |
); | |
$professor = preg_replace('/\s{2,}/', '|', trim($valor[13]->plaintext)); | |
$dados[$id]['t'][trim($valor[4]->plaintext)] = array( | |
// Vagas | |
'v' => (int)trim($valor[7]->plaintext), | |
// Alunos (vagas ocupadas) | |
'a' => (int)trim($valor[8]->plaintext), | |
// Alunos especiais | |
'e' => (int)trim($valor[9]->plaintext), | |
// Horários da aula/sala | |
'h' => $horarios, | |
// Professor(es) | |
'p' => explode('|', $professor), | |
); | |
} | |
} | |
// Configuração do horário para o output | |
date_default_timezone_set('America/Sao_Paulo'); | |
$i = 0; | |
$campi = $dom->find('select[id="formBusca:selectCampus"] option'); | |
for($campus = 0, $max = count($campi); $campus < $max; ++$campus) { | |
$dados = array(); | |
$i = 0; | |
do { | |
echo '[', date('H:i:s'), '] ', $campi[$campus]->innertext, ': parseando dados da página ', ++$i, PHP_EOL; | |
parse_ufsc_xhtml($dom, $dados); | |
$buttons = $dom->find('td.rich-datascr-button'); | |
$hasnext = count($buttons) && strpos($buttons[4]->class, 'rich-datascr-button-dsbld') === FALSE; | |
request_next_page($ch, $dom, $post_turmas_fields); | |
$view_state = $dom->find('input[name="javax.faces.ViewState"]')[0]->value; | |
} while ($hasnext); | |
file_put_contents(str_replace('UFSC/', '', $campi[$campus]->innertext) . '@' . $post_turmas_fields['formBusca:selectSemestre'] . '.json', json_encode($dados)); | |
request_next_campus($ch, $dom, $post_turmas_fields); | |
} | |
exit('Parseado com sucesso!' . PHP_EOL); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment