R/utils.R

Defines functions download ler desenhar classificar classificar_raw classificar_online visualizar

Documented in classificar classificar_online classificar_raw desenhar download ler

#' Pipe operator
#'
#' See \code{\link[magrittr]{\%>\%}} for more details.
#'
#' @name %>%
#' @rdname pipe
#' @keywords internal
#' @export
#' @importFrom magrittr %>%
#' @usage lhs \%>\% rhs
NULL

#' Download captcha
#' 
#' for(i in 1:100) {
#'  dest = sprintf("data-raw/captchas/captcha%05d.jpeg", i)
#'  download(dest)
#'  Sys.sleep(1)
#' }
#' 
#' @param dest destino do arquivo que vc deseja salvar o captcha
#' @export
#' 
download <- function(dest = NULL) {
  base <- 'http://www.receita.fazenda.gov.br/pessoajuridica/cnpj/cnpjreva'
  u <- paste0(base, '/cnpjreva_solicitacao2.asp')
  captcha <- xml2::read_html(u) %>%
    rvest::html_nodes("#imgCaptcha") %>%
    rvest::html_attr("src")
  captcha <- gsub('^\\.', '', captcha)
  if(is.null(dest)) dest <- tempfile()
  download.file(url = paste0(base, captcha), destfile = dest)
  return(dest)
}


#' Ler Captcha
#'
#' copiada do captchasaj/ só mudei que o arquivo é JPEG
#' agora é PNG denovo :P
#' 
#' @export
#' 
ler <- function(a) {
  img <- png::readPNG(a)
  img_dim <- dim(img)
  img_df <- data.frame(
    x = rep(1:img_dim[2], each = img_dim[1]),
    y = rep(img_dim[1]:1, img_dim[2]),
    r = as.vector(img[,,1]),
    g = as.vector(img[,,2]),
    b = as.vector(img[,,3])
  )
  d <- dplyr::mutate(img_df, cor = rgb(r, g, b), id = 1:n())
  d <- dplyr::filter(d, cor != '#FFFFFF')
  d
}

#' Desenhar Capctha
#'
#' copiada do captchasaj
#' 
#' @export
#' 
desenhar <- function(d){
  p <- ggplot2::ggplot(d, ggplot2::aes(x = x, y = y))
  p <- p + 
    ggplot2::coord_equal() + 
    ggplot2::theme_bw()
  if(!is.null(d$grupo)) {
    p <- p + ggplot2::geom_point(shape = 15)
    p <- p + ggplot2::facet_wrap(~grupo, scales = 'free_x', ncol = 6)
  } else {
    p <- p + ggplot2::geom_point(colour = d$cor, shape = 15, size = 3)
  }
  p +
    ggplot2::scale_x_continuous(breaks = 0:1000 * 3) +
    ggplot2::scale_y_continuous(breaks = 0:100 * 5)
}

#' classificar Capctha
#'
#' adaptada do captchasaj
#' 
#' @export
#' 
classificar <- function(d, letras = NULL, path) {
  if(is.null(letras)) {
    letras <- readline(prompt="Letras: ")
  }
  r <- strsplit(letras, '')[[1]]
  for(i in 1:6) {
    aux <- d[d$grupo == i, ]
    nm <- sprintf('%s/%s_%07d.rds', path, r[i],
                  as.integer(round(runif(1, 1, 1e8-1))))
    saveRDS(aux, nm)
  }
}

#' classificar Capctha, raw
#'
#' adaptada do captchasaj
#' TODO: usar site para validar captcha, pois eh muito dificil e podemos
#' criar uma base de treino com erros
#' 
#' @export
#' 
classificar_raw <- function(d, path) {
  letras <- readline(prompt = "Texto: ")
  if(letras == '?') return('nao sei')
  if(length(strsplit(letras, '')[[1]]) != 6) {
    stop('insira 6 caracteres -.-')
  }
  nm <- sprintf('%s/%s_%07d.rds', path, letras,
                as.integer(round(runif(1, 1, 1e8-1))))
  saveRDS(d, nm)
}


#' classificar Capctha, online, verificando se ta certo
#' 
#' @export
#' 
classificar_online <- function(n, path_temp, path_corretos, path_errados,
                               display = FALSE) {
  #   base <- 'http://www.receita.fazenda.gov.br/pessoajuridica/cnpj/cnpjreva'
  #   link1 <- paste0(base, '/cnpjreva_solicitacao2.asp?cnpj=60746948000112')
  #   r <- httr::GET(link1)
  #   captcha <- xml2::read_html(r) %>%
  #     rvest::html_nodes("#imgCaptcha") %>%
  #     rvest::html_attr("src")
  #   u_captcha <-  paste0(base, gsub('^\\.', '', captcha))
  #   dest <- tempfile()
  #   r_captcha <- httr::GET(u_captcha, httr::write_disk(dest))
  #   d <- ler(dest)
  #   unlink(dest)
  #   rm(dest)
  #   print(desenhar(d))
  #   
  #   letras <- readline(prompt = "Texto: ")
  #   
  #   link2 <- paste0(base, '/valida.asp')
  #   dados <- list(origem = 'comprovante',
  #                 cnpj = '60746948000112',
  #                 txtTexto_captcha_serpro_gov_br = letras,
  #                 submit1 = 'Consultar',
  #                 search_type = 'cnpj')
  #   res <- httr::POST(link2, body = dados, httr::set_cookies("flag" = 1))
  #   link3 <- paste0(base, '/Cnpjreva_Vstatus.asp?origem=comprovante&cnpj=60746948000112')
  #   res3 <- httr::GET(link3)
  #   
  #   
  #   crawlr:::visualize.response(res3)
  #   
  #   # Todo...
  #   res
  a <- system.file('python/valida_online.py', package = 'captchaReceita')
  rPython::python.assign('mostrar_browser', display)
  rPython::python.load(a)
  Sys.sleep(5)
  m_rf <- readRDS('data/modelo_RF.rds')
  m_svm <- readRDS('data/modelo_SVM.rds')
  m_stack <- readRDS('data/m_stack.rds')
  
  progress_text <- plyr::progress_text
  progress_bar_text <- plyr::create_progress_bar("text")
  progress_bar_text$init(n)
  
  replicate(n, {
    rPython::python.call('acessar')
    rPython::python.call('salvar_img', path_temp)
    arq_temp <- paste0(path_temp, '/out.png')
    txt <- '!ERRO!'
    valido <- FALSE
    try({
      txt <- decodificar_stack(arq_temp, m_rf, m_svm, m_stack)
      valido <- rPython::python.call('validar', txt)
    }, TRUE)
    d <- ler(arq_temp)
    if(valido) {
      saveRDS(d, sprintf('%s/%s_%07d.rds', path_corretos, txt,
                         as.integer(round(runif(1, 1, 1e8-1)))))
    } else {
      saveRDS(d, sprintf('%s/%s_%07d.rds', path_errados, txt,
                         as.integer(round(runif(1, 1, 1e8-1)))))
    }
    progress_bar_text$step()
  })
  rPython::python.call('fechar')
}


#' Visualizar como foi o processamento das letras
#'
#' @param treino base usada no treino
#' @param carac caracter que você deseja visualizar
#' @param qtd quantidade de imagens para visuzalizar
#' 
#' @export
visualizar <- function(treino, carac, qtd = 50){
  # data(treino)
  tb <- treino[treino$letra == carac,]
  tb <- tb[sample(1:nrow(tb), size = qtd),]
  tb <- tb %>%
    dplyr::mutate(id = 1:nrow(.)) %>%
    tidyr::gather(pixel, r, starts_with("x")) %>%
    tidyr::separate(pixel, c("x", "y")) %>%
    dplyr::mutate(
      x = as.numeric(stringr::str_replace_all(x, "x", "")),
      y = as.numeric(stringr::str_replace_all(y, "y", ""))
    )
  tb %>% 
    dplyr::filter(r == 1) %>%
    ggplot2::ggplot(ggplot2::aes(x = x, y = y)) + ggplot2::geom_point() + ggplot2::facet_wrap(~id)
}

#' Corrige classificacoes erradas
#' 
#' @export
#' 
corrigir_errados <- function(path_errados, path_corretos) {
  arqs <- dir(path_errados, full.names = TRUE)
  for(a in arqs) {
    d <- readRDS(a)
    cat(sprintf('chute: %s\n', 
                str_sub(str_extract(a, '[A-Z0-9]{6}_[0-9]{7}'), 1L, 6L)))
    print(desenhar(d))
    classificar_raw(a, path_corretos)
    file.remove(a)
  }
}
jtrecenti/captchaReceita documentation built on May 20, 2019, 3:16 a.m.