Web Scraping, WhatsApp, CAPTCHA e Ética

Web Scraping, e reduto da extração de dados na internet. Essa prática é tão antiga que data dos bots dos robôs de busca que já a aplicavam mesmo antes de muitos de vocês leitores terem nascido.

Sim, meu caro padawan, se você achava que estava inovando escrevendo um script em Python ou VBA para extrair dados de uma página web, pense de novo! Há uma quantidade insana de bots e spiders fazendo isso desde os tempos remotos da World Wide Web.

Pra variar, a tecnologia não perdoou e tornou cada vez mais fácil fazer esse tipo de extração de dados, mesmo para profissionais cuja rotina nada tem de relacionada com programação. Nisso entra o VBA, provavelmente a opção de automação de mais fácil alcance e didática presente no mercado.

Até aqui, tudo bem, o web scraping está aí, é fácil de fazer, ferramentas tem aos montes, sites-alvo mais ainda. Mas (sempre tem um mas) enquanto muitos passam tempo tentando descobrir o como, poucos se perguntam se realmente deveriam estar fazendo isso. 

Web Scraping e Ética?

Para o quê e quando fazer web scraping é uma pergunta que, para ser respondida, deveria sempre ter um contexto ético. Não vou entrar no mérito filosófico da questão, já que em tempos atuais o que mais tem é filósofo discutindo ética na internet. Vou basear a crença deste texto na seguinte definição:

Ética: tudo aquilo que você faz mesmo quando ninguém está olhando.

Ou seja, quando você faz web scraping de um website, você deveria sim se perguntar se você deveria estar fazendo-o. Um site quando é publicado tem a intenção primária de fornecer conteúdo legível para humanos. Quando um script entra em jogo, isso cai por terra. Ao invés de um ser humano limitado a um certo número de cliques e com uma capacidade regular de ler e interpretar textos, um bot consegue repetir a operação de clicar, baixar e salvar diversas páginas numa fração desse tempo.

Dentre vários problemas que isso pode causar, posso pensar em:

  1. O site não foi feito para aguentar tal carga de acessos
  2. Os termos e condições não permite a cópia dos dados
  3. E mais importante, o autor do site tem o direito exigir interação humana no site

Sim, Termos e Condições, aquela coisa que, assim como contratos, pouquíssimos lêem.

Termos de Condições

Vou ser claro, não sou advogado, mas já tive a oportunidade de conversar muito com vários para ter uma noção honesta do que pode acontecer se você não andar na linha. Posto isto, vamos em frente.

Quando um site exibe um texto detalhando Termos e Condições, as chances de haver uma séria limitação de acesso ao uso seu conteúdo é quase certa. 

Essas limitações atingem principalmente robôs, que nada mais são que aplicativos criados para acessar o conteúdo de um website. Sabe aquele script em VBA que você criou para extrair dados de uma página web? Pois é, ele entra nessa categoria.

No geral, não é preciso se preocupar na maior parte dos casos já que o problema está em como você usa a informação e não como ela é extraída. Mas (outro mas aqui), toda vez que você pensar em fazer qualquer tipo de extração automatizada, você deveria ler os Termos e Condições.

E sim, você deveria estar se perguntando se alguma vez você já fez isso.

Por que isso é tão importante? Porque ter acesso a um dado é diferente do uso que se faz dele, e isso comumente está claro nos Termos e Condições, que normalmente detalha não só as regras e limitações como as penalidades aplicadas.

Quando você deveria fazer web scraping

Existe um cenário ideal para quando você deveria fazer web scraping sem se preocupar muito. A maneira mais fácil de identificar tal cenário é quando você já está fazendo alguma operação manual, como por exemplo extrair dados de venda para construir um relatório específico que não está disponível num sistema interno da empresa. Ao invés de copiar e colar uma centena de dados, o que não só levaria um tempo considerável como também estaria sujeito a erros, você pode automatizar isso.

Esta é uma situação perfeita para aplicar web scraping. Os dados são da empresa, serão utilizados pela empresa e o usuário que precisa deles não tem acesso a eles de outra forma que não pelo próprio.

Qualquer coisa que vá além disso (resumindo, tudo o que não é seu) cai no filtro dos Termos e Condições.

Quando você NÃO deveria fazer web scraping

Existem diversos sinais que deixarão claro que um web scraping não é bem vindo. Não vou entrar em detalhes sobre robots.txt e outras minúscias. Isto é algo que ficará para um curso de Web Scraping que lançarei num futuro próximo.

Então, quando não é aconselhável fazer web scraping? Os exemplos abaixo são os mais comuns:

  • O site expõe um CAPTCHA
  • O site protege a informação através de login e senha
  • O site ou o detentor dele expõe formas mais adequadas de extrair a informação, como através de web services (SOAP/REST)
  • O site bloqueia seu acesso caso ele for muito frequente
  • O site não permite extração de dados de forma automatizada (Termos e Condições, lembra?)

Vale a pena detalhar um pouco mais o primeiro item citado.

CAPTCHA

Isso mesmo, aquela coisa horrorosa que temos que decifrar
Isso mesmo, aquela coisa horrorosa que temos que decifrar

O CAPTCHA é um Teste de Turing aplicado em uma página web. Para leigos, é basicamente uma maneira moderna de impedir que uma máquina se passe por um ser humano real. A razão para isso é simples: sites são conteúdos visuais, feitos para humanos consumirem. Se uma máquina/robô/script vem atazanar aquele lindo website que você construiu com tanto esforço e paga com o suor do seu trabalho para ficar hospedado, você vai querer saber o que está acontecendo.

Para evitar que seu conteúdo seja lido ao léu por robôs que querem mais é tirar proveito de informação alheia, a internet bolou formas de bloquear o acesso, sendo a mais conhecida e utilizada o CAPTCHA.

Como mencionado acima, seu script VBA entra na categoria de robôs da internet, por isso, o CAPTCHA está lá para atrapalhar a vida dele.

Por isso, toda vez que você der de cara um com desses ao escrever seu lindo web scrapper, saiba existe um motivo muito bom para ele estar lá.

E o WhatsApp?

O WhatsApp entra de vítima nessa história por alguns motivos específicos:

  • Há uma versão web/desktop que pode ser usada
  • Como todo site/app, ele também funciona sob determinados termos de condições, algo que já discutimos aqui
  • O WhatsApp é de longe o aplicativo de mensagens mais utilizado no Brasil, o que o torna alvo de todo tipo de ação que foca em atingir massas (leia-se spam)
  • O WhatsApp é do Facebook, uma gigante da indústria da internet com muito $$$ para gastar e ela não poupará em revidar se um mau uso for feito do seu aplicativo, já que este pode ser usado de graça

Recentemente a publicação deste texto, o jornal The Economic Times publicou uma matéria detalhando que o WhatsApp vai processar qualquer um que fizer uso do aplicativo para envio de mensagens em massa. Link aqui (em inglês): https://economictimes.indiatimes.com/tech/internet/whatsapp-will-take-you-to-court-if-you-send-bulk-messages-misuse-app/articleshow/69783647.cms?from=mdr

Ou seja querido scripteiro, se você estiver fazendo uso do WhatsApp desktop para fazer envio de mensagens em massa, você está infringindo o regulamento do aplicativo e sujeito a penalização.

Se você se perguntava porque até agora eu não tinha publicado um tutorial de Selenium e WhatsApp, bem, aí está sua resposta.

Fazendo Mock da Classe HttpClient

O problema?

Ainda que você não viva no mundo dos micro-serviços, uma hora você vai precisar chamar um serviço REST em outra ponta via HTTP/S, e no caso do AspNetCore, o jeito mais natural de fazê-lo é via a classe HttpClient.

Até aqui, tudo tranquilo, os métodos Get, Post, Put, Patch e Delete (talvez até outros) estão lá para serem usados. O problema é, caso sua implementação precise passar por testes unitários, a classe HttpClient pode lhe trazer problemas, já que não há interface disponível para mock e os métodos acima citados não são virtual.

Note que citei que ela “pode” lhe trazer problemas. Como fazer então para que a classe HttpClient não seja um para seus testes unitários?

Tudo se resume ao SendAsync

Se há algo que é mágico no AspNetCore é que ele é código aberto. Isso mesmo, você ir lá no github e ter acesso ao código fonte de praticamente 100% das classes que você usa no seu projeto. E, felizmente, esse é a caso do HttpClient. Vou deixar o link do fonte no fim do artigo.

Dando uma lida na classe, que é bem escrita por sinal, percebe-se que todos os métodos REST com exceção do Get, chamam um método chamado SendAsync, que recebe como parâmetro um objeto HttpRequestMessage e opcionalmente um CancellationToken.

O HttpRequestMessage precisa basicamente do corpo que você enviaria via Post, Put, Patch e Delete. O ponto de atenção é que somente a versão com o CancellationToken é virtual/override. Se você sabe o que o CancellationToken é, você deveria estar usando-o. Caso não, use CancellationToken.None por agora.

O código de exemplo abaixo faz um Post usando HttpClient:

public class MeuController : ControllerBase
{
	private readonly HttpClient client;

    public MeuController(HttpClient client)
    {
        this.client = client;
    }

	public async Task AlgumPost(Criterios criterios)
	{    
	    // estou ignorando quaisquer configurações de header
	    // também estou assumindo que a classe HttpClient é injetada via construto
		var stringContent = new StringContent(JsonConvert.SerializeObject(criterios), Encoding.UTF8, "application/json");
		var result = await this.client.PostAsync($"url", stringContent, CancellationToken.None);
		return Ok(result);
	}
}

O código é até simples. Agora, o teste unitário que permite você fazer o “mockar” a chamada PostAsync seria o seguinte:

public async Task DeveriaExecutarOSendAsyncAoMenosUmaVez()
{
	// assumindo o uso do Moq e xUnit
	var httpClient = new Mock();
	httpClient
	    .Setup(x => x.SendAsync(It.IsAny(), CancellationToken.None))
	    .ReturnsAsync(new HttpResponseMessage()
	    {
	        StatusCode = HttpStatusCode.OK,
	        Content = new StringContent("{}"),
	    }).Verifiable();

	var controller = new MeuController(
	    httpClient.Object
	);

	var criterios = new Criterios() { };

	var result = await controller.AlgumPost(criterios);

	httpClient.Verify(x => x.SendAsync(It.IsAny(), CancellationToken.None), Times.Exactly(1));
}

O teste acima passa com sucesso! Note que não estamos fazendo Mock do PostAsync, mas do SendAsync já que o primeiro não pode ser “mockado”, mas ele chama o segundo. Caso queira checar que a chamada tenha sido correta, basta usar o CallBack oferecido pelo Moq.

Mas e o Get/GetString/GetStringAsync?

O que fazer então com os Gets? Simples! Não os use! Digo isso com certeza pois há uma alternativa muito mais limpa para ele. O próprio Send/SendAsync!

O problema dos Gets é que não há um meio apropriado de tratar erros. Se o request falhar, uma Exception pode ser disparada ou não.

O substituto ideal seria o seguinte:

// ao invés disso
public async Task ObterConteudo()
{
	var resultado = await this.client.GetStringAsync("https://alguma.api.por.ai");
	return Ok(resultado);
}

// faça isso
public async Task ObterConteudo()
{
	var requestMessage = new HttpRequestMessage(HttpMethod.Get, "https://alguma.api.por.ai");
	var response = await this.client.SendAsync(requestMessage);

	if (response.IsSuccessStatusCode)
	{
	    var resultado = JsonConvert.DeserializeObject(await response.Content.ReadAsStringAsync());
	    return Ok(resultado);
	}
	else
	{
	    return StatusCode((int)response.StatusCode, response.Content.ReadAsStringAsync().Result);
	}
}

Desta forma, o retorno dado ao cliente é muito mais “honesto” e de quebra, você ganha a oportunidade de testá-lo apropriadamente.
Bom proveito!

Código fonte da classe HttpClient:

https://github.com/dotnet/corefx/blob/master/src/System.Net.Http/src/System/Net/Http/HttpClient.cs

Aqui uma implementação de código funcionando:

https://github.com/Tomamais/dotnet_mocking_httpclient

Excel – BDSOMA, BDMULTIPL, BD… e as funções do excel que você deveria conhecer

20 anos usando o Excel e ele ainda me surpreende. E sabe o que é mais curioso? Ele te surpreende com recursos que sempre estiveram lá, há anos, muitos, mas você nunca notou!

Este é o caso das funções de Banco de Dados, ou BD*.

Eu tive contato com estas fórmulas no começo da minha vida no Excel, mas, seja pela forma como ela foi explicada ou minha falta de experiência, acabei não sabendo o que fazer com elas e acabei deixando pra lá.

Não vou abordar todas aqui, primeiro, porque uma vez que você aprenda a usar uma, as outras seguem o mesmo raciocínio de uso, tornando fácil a adaptação, segundo, a lista é longa, terceiro… já esqueci, mas vamos ao que interessa.

No fim do artigo tem uma lista de TODAS as funções de banco de dados do próprio site da Microsoft para você conferir.

É hora do show!

Vou usar aqui o BDSOMA. Ele vai resumir o espetáculo que utilizar as funções de banco de dados. Vou aplicar o conceito máximo do reaproveitamento e utilizar o próprio exemplo da Microsoft.

Considere a tabela de dados abaixo:

ABCDE
1ÁrvoreAlturaIdadeRendimentoLucro
2Maçã182014$105
3Pera121210$96
4Cereja13149$105
5Maçã141510$75
6Pera988$77
7Maçã896$45

Uma lista de simples de pés-de-alguma fruta, coisa que todo morador de interior já teve no quintal de casa.

Para o exemplo, se quisermos extrair a SOMA dos rendimentos, fica fácil, se quisermos extrair a SOMASE a árvore for de Maçã, também fica fácil. Mas, se quisermos extrair a soma se a árvore for Maçã e os redimentos forem maiores que 10 e menores do que 16, precisamos pensar um pouco.

Se você for um pouco letrado no Excel, sabe que isso se resolve com um SOMASES com a seguinte fórmula:

=SOMASES(D2:D7;B2:B7;”>10″;A2:A7;”=Maçã”;B2:B7;”<16″)

Mas, se complicarmos um pouco mais, gerando critérios múltiplos para nossa soma, você precisa ou elaborar muito o SOMASES ou utilizar mais de um. Por exemplo, se eu quiser incluir a soma de tudo o que for Pera, a fórmula fica assim:

=SOMASES(D2:D7;B2:B7;”>10″;A2:A7;”=Maçã”;B2:B7;”<16″)+SOMASES(D2:D7;A2:A7;”=Pera”)

Resolve, mas é “feio”.

Nada contra o SOMASES, o problema é que, se você precisa repetir uma fórmula, a probabilidade de existir uma solução mais simples é inegável. Outra reclamação pessoal que tenho é que, para entender o que está acontecendo, eu basicamente tenho que decifrar a fórmula, ou seja, entrar na célula e lembrar o que ela está fazendo. Para fórmulas simples, isso não é problema, mas para coisas medonhas que requerem quebras de linha, não é tão simples.

Isso não acontece quando você utiliza o BDSOMA. Vamos aplicar o mesmo critério de soma detalhado acima usando-a. Abaixo, a planilha um pouco transformada:


ABCDEF
1ÁrvoreAlturaIdadeRendimentoLucroAltura
2=Maçã>10<16
3=Pera
4
5ÁrvoreAlturaIdadeRendimentoLucro
6Maçã182014$105
7Pera121210$96
8Cereja13149$105
9Maçã141510$75
10Pera988$77
11Maçã896$45

Eu já gosto mais do que estou vendo. Em resumo, a tabela principal foi empurrada algumas linhas para baixo e deu espaço ao que vou chamar de área de filtros ou critérios. Ou seja:

A5:E11 – São os dados que queremos trabalhar

A1:F3 – Os filtros a serem aplicados

Usando o BDSOMA, o mesmo resultado do SOMASES pode ser conseguido com a seguinte fórmula:

=BDSOMA(A5:E11;”Rendimento”;A1:F3)

Explicando a fórmula acima:

  • A5:E11 é obviamente a área de dados a ser avaliada
  • “Rendimento” é a coluna que queremos somar. Sim, você não precisa mencionar índice ou coisa parecida. Basta o nome
  • A1:F3 são os filtros, que podem ser repetidos, unidos e cruzados! Veja que temos duas linhas para dizer que queremos árvores de Maçã OU Pera, e no caso da Maçã, com altura >10 (célula B2) e <16 (célula F2)

Não sei para você leitor, mas para mim, isso é mágico! Os filtros estão à mostra e sei EXATAMENTE o que está sendo considerado na soma! E posso mudar à vontade a área de filtros para ver o resultado mudar, sem precisar mexer na fórmula! Experimente!

Sim, você pode chegar num resultado parecido com o SOMASES, mas dá mais trabalho, já que não é natural.

O formato utilizado é só uma convenção, sendo que os filtros podem ser colocar em qualquer lugar do seu arquivo.

“Mas se eu quiser o PRODUTO? Ou a MÉDIA?”. Oh meu caro padawan, divirta-se com a lista abaixo que utiliza a mesma estrutura do BDSOMA:

Função Descrição
BDMÉDIARetorna a média das entradas selecionadas de um banco de dados
BDCONTARConta as células que contêm números em um banco de dados
BDCONTARAConta células não vazias em um banco de dados
BDEXTRAIRExtrai de um banco de dados um único registro que corresponde a um critério específico
BDMÁXRetorna o valor máximo de entradas selecionadas de um banco de dados
BDMÍNRetorna o valor mínimo de entradas selecionadas de um banco de dados
BDMULTIPLMultiplica os valores em um campo específico de registros que correspondem ao critério em um banco de dados
BDESTEstima o desvio padrão com base em uma amostra de entradas selecionadas de um banco de dados
BDDESVPACalcula o desvio padrão com base na população inteira de entradas selecionadas de um banco de dados
BDSOMASoma os números na coluna de campos de registros do banco de dados que correspondem ao critério
BDVARESTEstima a variação com base em uma amostra de entradas selecionadas de um banco de dados
BDVARPCalcula a variação com base na população inteira de entradas selecionadas de um banco de dados

Você sabe o que é Power BI? Nem eu…

Faz tempo que não escrevo um artigo de opinião. Já era hora de desenferrujar e nada melhor do que polemizar para tal.

Não custa ressaltar que o que escreverei aqui é apenas MINHA OPINIÃO e não necessariamente reflete a verdade ou o que a comunidade pensa. E, por mais que o Power BI esteja mencionado no título, eu não falarei dele.

Sabendo disso, vamos em frente.

A bola da vez?

O assunto da vez, pelo menos no que tange o espectro de curiosos e interessados do Excel, é o Power BI e com ele, os Dashboards.

Não vou entrar no mérito do segundo por ele ser mais abrangente. Isso tem mais ou menos uns 2 a 3 anos da data deste post. Só se fala nele, só se dá curso sobre ele, masterclass, livros, etc. Isso é bom, aquece o mercado, alimenta famílias, engrandece o currículo.

MAS (em caixa alta mesmo) , se você sofre um mínimo do complexo de vira-lata, o que é o meu caso, provavelmente se sentiu “atrasado” em saber que nada sabia sobre o assunto. Como tudo curioso frustrado, fui lá tentar saber o que era. Para minha surpresa, o que encontrei foi isso…

O Power BI não é para mim, e talvez não seja para você

O subtítulo acima foi feito para incomodar, principalmente aos adoradores no Power BI. Entendo, mas há algo que precisa ficar claro aqui.

O Excel é um software com uma quantidade insana de funcionalidades. Nem mesmo os mais experientes conseguiriam enumerar todas, e eles admitem isso (vou deixar para você o trabalho de pesquisar isso. Minha dica é gastar um tempo no Quora vendo respostas dos MVPs).

Diante disso, toda vez que algum recurso revolucinário vem à tona, a primeira coisa que me vem a cabeça é ceticismo, e isso eu aprendi com o João Benito Savastano. Depois de quase 20 anos conhecendo e trabalhando com a ferramenta, achar que falta algo é “meio que” trair a confiança dela.

Não me leve a mal, eu gosto de novidades, tanto que faço questão de sempre ter a última versão do Office instalada no meu Windows. Mas, para ser sincero, depois do SOMASES, CONCAT e UNIRTEXTO, pouca coisa fez diferença para mim, e o Power BI é uma delas. Não é porque o Power BI é ruim. Os colegas da comunidade estão fazendo trabalhos Excelentes divulgando a ferramenta, escrevendo artigos, ministrando cursos e escrevendo livros.

Só que, bem, o Power BI não é para mim, e por alguns motivos simples:

  • ele não tornará meu trabalho melhor
  • ele não tornará meu trabalho mais rápido
  • meus projetos não se beneficiarão dele
  • meus clientes não se beneficiarão dele
  • eu gosto de Dashboards, mas nem meus clientes e nem eu precisamos deles

Isso é mais do que suficiente para eu não me preocupar com ele por enquanto, ou pelo menos até ele ser necessário para mim.

Coitado do Power BI

Aqui, um mea culpa. Eu basicamente massacrei o Power BI sem mesmo tê-lo conhecido. A verdade é que ele acabou sendo o bode expiatório de um problema maior que tentei elaborar acima.

Por isso, para qualquer outro recurso maluco que você acha que deveria conhecer, mas não conhece, pense que, se você é capaz de fazer seu trabalho com produtividade com os recursos que você já sabe, isso é tudo o que você precisa e você pode tranquilamente viver sem nada saber da “nova funcionalidade no pedaço”.

Conhecer coisas novas é tarefa obrigatória de todo profissional da atualidade, mas, com o tempo escasso e o mercado exigente, ser seletivo no que você vai utilizar é o melhor caminho a seguir.

Desculpe Power BI. Quem sabe no futuro…

Tecnologia e Programação