Acessar páginas na internet e extrair informações simples abre a possibilidade para a criação de diversas aplicações. Sendo assim, nesta aula, vamos aprender a fazer requisições GET e POST em domínios na internet.

Na aula anterior, aprendemos a enviar e receber dados pelo Web Server criado no NodeMcu.


Informações importantes

Não pretendo descrever sobre os diversos métodos de requisição de dados, pois já descrevi eles na aula anterior. Portanto, vamos ver apenas como implementá-los para extrair dados de um site qualquer na internet.

Vale mencionar que, de acordo com alguns testes que fiz, o NodeMcu possui alguns problemas com os módulos para comunicação http. Pois, na hora de comunicar com alguns sites, ocorrem erros e não há muito o que ser feito. Isso é bem ruim, pois ficamos limitado quanto às aplicações possíveis, como mencionei no começo do post.

Um obstáculo que encontrei foi tentar extrair informações do site do correio (o estado de um encomenda), pois só recebi erros. Enfim, mas existem outros casos que funcionam (este próprio site), então vale a pena aprender a acessar os dados mesmo assim.


Como descobrir o método certo

Para quem não tem muito conhecimento sobre o protocolo HTTP, descobrir a forma certa de fazer uma requisição é uma tarefa extremamente complicada. Mas existe uma forma bem fácil de descobrir como fazê-la de forma bem completa. Essa forma utiliza a ferramenta de desenvolvimento do Google Chrome, e é também possível utilizar a ToolBox do Mozilla.

Vamos ao passo a passo:

  • Primeiro, abra a página que você deseja fazer a requisição.
  • Em seguida, aperte F12 no teclado para abrir a janela de desenvolvimento e clique na aba “Network”
  • Recarregue a página e aguarde a janela de desenvolvimento mostrar os resultados
  • Dentre os resultados, pode haver uma série de requisições que o navegador fez com o servidor da página que você está tentando acessar. Nesta parte, você deve encontrar a requisição desejada. Por exemplo, na imagem abaixo, a requisição desejada foi a de acessar a própria página (post de sensor de obstáculo) e o nome da requisição ficou bem óbvio.

Descobrindo o método de requisição certo

Talvez seja útil marcar o tipo “Doc” para não exibir alguns pacotes que talvez sejam desinteressantes.

  • Por fim, clique na requisição e veja algumas informações úteis a respeito dela. No exemplo abaixo, podemos ver que a requisição é do tipo GET. Podemos verificar também o cabeçalho de resposta (Response Headers) e o cabeçalho da requisição (Request Headers). Dentro do cabeçalho da requisição é que entendemos como fazer o pedido corretamente.

Descobrindo o método de requisição certo

Requisição com POST

Para o caso em que é desejado entender como fazer a requisição de preencher um campo e clicar em um botão, o processo não é diferente. Primeiro deve-se acessar a página em que o botão e o campo a ser preenchido se encontram. Dentro da página, aperte F12, clique em Network, para então preencher o campo e clicar no botão de envio. Em seguida a janela de desenvolvimento irá gravar a requisição de submit.

Por fim, é só repetir as etapas finais mostradas anteriormente. No exemplo abaixo, fui no site dos correios e fiz o teste preenchendo o campo de rastreamento e clicando no botão para rastrear uma encomenda. O resultado retornado mostra também a seção “Form Data” com os dados enviados da forma certa.

Descobrindo o método de requisição dos correios

 

Tendo conhecimento desse método útil, podemos seguir para a implementação das requisições no NodeMcu.


Implementação

Existem duas formas de fazer requisições com o NodeMcu. A primeira é utilizando o módulo HTTP e a outra é utilizando o módulo NET. Mostrarei o exemplo das duas, já que há requisições que funcionam apenas em uma delas.

Módulo HTTP

Comandos

O módulo HTTP é bem direto, necessitando apenas de praticamente um único comando para fazer uma requisição. Mostrarei apenas a utilização com o método GET e POST, pois o restante é fácil de entender a partir destes dois.

Para fazer uma requisição GET, usamos o comando:

http.get(url, cabeçalho, função associada)

No comando acima, precisamos definir qual é a página acessada (url) e o cabeçalho (mostrado no tópico anterior). Não é necessário definir algo para o cabeçalho, então ele pode ter o valor de ‘nil’ (nulo). Por fim, a “função associada” é acessada quando a requisição receber uma resposta ou ocorrer um erro. Ela recebe dois parâmetros: um que é o código da resposta e o outro que é a própria resposta.

No caso da requisição POST, temos o seguinte comando:

http.get(url, cabeçalho, corpo, função associada)

Os parâmetros são praticamente os mesmos, com a diferença do “corpo”. O “corpo” é o parâmetro onde são passados os dados a serem submetidos à página. Nos exemplos abaixo, mostrarei como utilizar os comandos para fazer requisições.

Exemplo 1 – GET

Para os dois exemplos, usarei o site ‘http://httpbin.org/‘ que permite testar as requisições. No caso do método GET, devemos usar o endereço ‘http://httpbin.org/get’. E as informações retornadas apresentam o seguinte formato:

{
  "args": {}, 
  "headers": {}, 
  "origin": "endereço-ip", 
  "url": "http://httpbin.org/get"
}

São dados que não tem muita utilidade, mas que servem para testar a comunicação entre o NodeMcu e um servidor externo.

Enfim, para o código completo do exemplo, precisamos fazer o NodeMcu conectar ao wi-fi e aguardar a conexão, assim como foi visto nas aulas passadas. Por fim, basta utilizarmos o comando mostrado no tópico anterior com o link desejado.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
wifi.setmode(wifi.STATION)
wifi.sta.config {ssid="NOME_DA_REDE_WIFI", pwd="SENHA_DA_REDE"}

tmr.alarm(0, 1000, 1, function() --Aguarda conectar na rede
    if wifi.sta.getip() == nil then
        print("Conectando à rede...\n")
    else
        ip=wifi.sta.getip()
        print("IP: ",ip)
        tmr.stop(0)
    end
end)

url = 'http://httpbin.org/get' --Cria uma variável para o endereço

function acessarSite1()
    http.get(url, nil, --Cabeçalho nulo (nil)
        function(code, data)
            print(code, data)
    end)
end

Para rodar o código, é só chamar a função no console do ESPlorer. E o resultado pode ser visto abaixo:

Resposta do método get do NodeMcu

O “200” é o código de resposta (significa OK).

Exemplo 2 – POST

Neste caso, o endereço utilizado é o ‘http://httpbin.org/post’ e o formato da resposta está apresentado abaixo:

{
  "args": {},
  "data": "dados-recebidos",
  "files": {},
  "form": {},
  "headers": {},
  "json": dados-recebidos,
  "origin": "endereço-ip",
  "url": "http://httpbin.org/post"
}

O código completo é igual ao do exemplo 1, com a diferença sendo a utilização do comando http.post() ao invés do http.get().

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
wifi.setmode(wifi.STATION)
wifi.sta.config {ssid="NOME_DA_REDE_WIFI", pwd="SENHA_DA_REDE"}

tmr.alarm(0, 1000, 1, function() --Aguarda conectar na rede
    if wifi.sta.getip() == nil then
        print("Conectando à rede...\n")
    else
        ip=wifi.sta.getip()
        print("IP: ",ip)
        tmr.stop(0)
    end
end)

url1 = 'http://httpbin.org/post' --Cria uma variável para o endereço
body = '{"input1":"dado1","input2":"dado2"}' --Cria uma variável para o corpo

function acessarSite2()
    http.post(url1, nil, body,
        function(code, data)
            print(code, data)
    end)
end

Para rodar o código, é só chamar a função no console do ESPlorer. E o resultado pode ser visto abaixo:

Resposta do método POST do NodeMcu

Repare que, dentro de ‘json’, temos os dados enviados por meio do corpo da requisição.

Módulo NET

Comandos

O módulo NET é um pouco mais complicado que o HTTP, pois é necessário utilizar mais comandos. O primeiro passo é criar uma conexão com o comando:

net.createConnection(net.TCP, 0)

Este comando cria um cliente com uma conexão TCP. O próximo passo, antes de conectar ao servidor desejado, é utilizar dois comandos que são acionados de acordo com certos eventos. Um comando será para imprimir os dados recebidos quando o evento “receive” ocorrer:

conn:on(“receive”, function(sck, payload) print(payload) end)

O segundo comando é para enviar os dados desejados quando o evento “connection” ocorrer (quando o NodeMcu conectar ao cliente):

conn:on(“connection”, function(conn) conn:send(“DADOS”) end)

No exemplo a seguir, mostrarei como é feito o envio dos “DADOS”.

Por fim, resta apenas fazer a conexão com o cliente:

conn:connect(80, host)

Host é o endereço do servidor assim como foi visto no começo deste post, e 80 é a porta do servidor. Normalmente a porta das páginas é 80 mesmo. Certo, agora temos tudo pronto para seguir para o exemplo.

Exemplo

Para exemplificar os comando net, vou acessar um post específico deste site e retornar o código html da página. O post escolhido foi o “Modo sleep com Arduino”. Sendo assim, acessando a página utilizando a ferramenta de desenvolvimento do Google Chrome, consigo ver como é enviado o cabeçalho da requisição GET:

cabeçalho da requisição get do post

Clicando em ‘view-source’ localizado no mesmo lugar de ‘view parsed’ antes de ser clicado, posso ver o cabeçalho na forma adequada para envio. E serão justamente esses dados que deverão ser enviados pelo conn:send(). Mas não é necessário enviar todos os parâmetros do cabeçalho, apenas os mostrados no código abaixo. E cada item é acompanhado de um ‘\r\n’ (retorno e pulador de linha).

Da mesma forma que os exemplos do tópico anterior, é necessário primeiro conectar o NodeMcu à rede wi-ifi, para depois extrair os dados da página. Temos então:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
wifi.setmode(wifi.STATION)
wifi.sta.config {ssid="NOME_DA_REDE_WIFI", pwd="SENHA_DA_REDE"}
 
tmr.alarm(0, 1000, 1, function() --Aguarda conectar na rede
    if wifi.sta.getip() == nil then
        print("Conectando à rede...\n")
    else
        ip=wifi.sta.getip()
        print("IP: ",ip)
        tmr.stop(0)
    end
end)

host = "mundoprojetado.com.br"
sublink = "/modo-sleep-com-arduino/"

function acessarSite3()
    conn = net.createConnection(net.TCP, 0)

    conn:on("receive", function(sck, payload) print(payload) end)
    conn:on("connection", function(conn)
        conn:send("GET " .. sublink .. " HTTP/1.1\r\n"
            .. "Host: " .. host .. "\r\n"
            .. "Connection: keep-alive\r\n"
            .. "Accept: */*\r\n"
            .. "\r\n")
    end)

    conn:connect(80, host)
end

Para rodar o código, é só chamar a função no console do ESPlorer. E parte do resultado (código html) pode ser visto abaixo:

Codigo HTML do post no NodeMcu

Podemos observar um trecho do html, em que aparece alguns parágrafos do post.

 

Com tudo o que foi mostrado, você deve ser capaz de fazer requisições mais interessantes. Mas lembrando que o NodeMcu apresenta erros inesperados na hora de acessar boa parte dos servidores.

Controlando NodeMcu por aplicativo Android – Aula 9 – NB