• Уважаемые посетители сайта esp8266.ru!
    Мы отказались от размещения рекламы на страницах форума для большего комфорта пользователей.
    Вы можете оказать посильную поддержку администрации форума. Данные средства пойдут на оплату услуг облачных провайдеров для сайта esp8266.ru
  • Система автоматизации с открытым исходным кодом на базе esp8266/esp32 микроконтроллеров и приложения IoT Manager. Наша группа в Telegram

Вопрос Поиск значения на web-странице

Прошу Вашего совета.
Необходимо получить необходимые данные с web страницы.
К примеру , esp8266 нужно узнать погоду в Лондоне с сайта sinoptik.ua/
Создается на esp web-client.
Он отправляет GET запрос на сайт
Погода в Лондоне. Прогноз погоды в Лондоне на сегодня, завтра и неделю. Англия - SINOPTIK.
Открывается страница sinoptik.ua с погодой в Лондоне.
Sinoptik.png
В коде страницы температура находится в теге
Значение.png
Как мне получить это значение " + 13 " ?
 

NeoroN

Member
Код примерно такой:
HTML:
<p class="today-temp">+10°C</p>
вначале надо найти "today-temp" затем от найденной позиции ищем конец тега ">" и запоминаем позицию, потом от найденной позиции ищем начало тега "<" в финале есть две позиции - извлекаем текст между ними.
Регулярными выражениями это сделать очень просто Regex101 - online regex editor and debugger
 

NeoroN

Member
Для начала предоставьте код который получает содержимое страницы в переменную типа String. Мне лень искать этот ваш web-client и переделывать его под ваши нужды.

Код:
String buf = String('<p class="today-temp">+10°C</p>');
unsigned int start = buf.indexOf('>',buf.indexOf("today-temp")+10);
unsigned int end = buf.indexOf('<',start+1);
String temp = buf.substring(start,end);
 
Последнее редактирование:

=AK=

New member
Для начала предоставьте код который получает содержимое страницы в переменную типа String. Мне лень искать этот ваш web-client и переделывать его под ваши нужды.

Код:
String buf = String('<p class="today-temp">+10°C</p>');
unsigned int start = buf.indexOf('>',buf.indexOf("today-temp")+10);
unsigned int end = buf.indexOf('<',start+1);
String temp = buf.substring(start,end);
Проще искать строку
Код:
<p class="today-temp">
при помощи find
 

NeoroN

Member
в Arduino нет <iostream> и соответвенно никаких find
А если писать на LUA то регуляркой проще...
 

pvvx

Активный участник сообщества
Прошу Вашего совета.
Необходимо получить необходимые данные с web страницы.
К примеру , esp8266 нужно узнать погоду в Лондоне с сайта sinoptik.ua/
По началу вам следует проверить, способен ли ESP8266 открыть TLS сессию с данным HTTPS сервером.
Снимок57.gif
Код:
#include <ESP8266WiFi.h>
#include <WiFiClientSecure.h>

char ssid[] = "";       // your network SSID (name) 
char password[] = "";  // your network key

WiFiClientSecure client;

void setup() {
  Serial.begin(115200);
  WiFi.mode(WIFI_STA);
  WiFi.disconnect();
  delay(100);
  Serial.print("Connecting Wifi: ");
  Serial.println(ssid);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    Serial.print(".");
    delay(500);
  }
  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  IPAddress ip = WiFi.localIP();
  Serial.println(ip);
}

char host[] = "sinoptik.ua";
void loop() {
  if (client.connect(host, 443)) {
    Serial.println("connected");
    client.println("GET / HTTP/1.1");
    client.print("Host: "); client.println(host);
    client.println("User-Agent: arduino/1.0");
    client.println("");
    delay(1000);
    while (client.available()) {
      char c = client.read();
      Serial.write(c);
    }
    client.stop();
  }
  delay(10000);
}
Код:
WiFi connected
IP address: 
192.168.1.225
connected
HTTP/1.1 302 Moved Temporarily
Server: nginx
Date: Wed, 25 Apr 2018 22:08:59 GMT
Content-Type: text/html
Content-Length: 154
Connection: keep-alive
Set-Cookie: os=UNKNOWN; path=/
Location: https://sinoptik.com.ru/
X-Server-By: sinfe1

<html>
<head><title>302 Found</title></head>
<body bgcolor="white">
<center><h1>302 Found</h1></center>
<hr><center>nginx</center>
</body>
</html>
 
Последнее редактирование:
По началу вам следует проверить, способен ли ESP8266 открыть TLS сессию с данным HTTPS сервером.
Загрузил Ваш скетч в ESP.
WiFi connected
IP address:
192.168.0.113
connected
HTTP/1.1 200 OK
Server: nginx
Date: Wed, 25 Apr 2018 23:24:45 GMT
Content-Type: text/html; charset=utf-8
Transfer-Encoding: chunked
Connection: keep-alive
Set-Cookie: os=UNKNOWN; path=/
X-Powered-By: PHP/5.5.38
X-Frame-Options: DENY
ETag: W/"74f7aed66760fa48be2a2293dd1202c6"
Vary: Accept-Encoding
X-Server-By: sinfe1

А потом в терминал он выдал весь код страницы. Там была искомая строчка с температурой.
Можно эти данные страницы сохранить в ESP и потом выделить это значение ?

Пробовал другие сайты подставлять. Не все работают . Точнее мало кто работает. С чем это может быть связано ?
(Прошу прощения за глупые вопросы. Не силен в программировании)
 

pvvx

Активный участник сообщества
Вам бы надо определиться - вариант делается для себя, с возможностью последующей смены кода, если что, ...
или вариант, который должен разбирать все ошибки?
или вариант универсальный, в качестве библиотеки для других, чтобы сменив пару строк можно было парсить любые сайты?

Я думаю, что первый вариант - написать как можно проще, чтобы как-то работало.
Для такого варианта достаточно найти совпадения любого кол-ва байт с искомым из строки "today-temp", лишь-бы они повторно не встречались до тега с нужной позиции с температурой. И хоть просто по смешению от них брать число температуры.

Для второго варианта вам уже потребуется определять код ответа сервера - разбирать протокол http...

Третьего варианта в Arduino для малых WiFi-SoC не встречается. Это возможно на Linux системах с PHP, Питоном, или ещё чаго.
 
Я думаю первого варианта для меня пока хватит.
Хочется понять алгоритм работы кода .
today-temp в коде страницы встречается всего один раз.
 

pvvx

Активный участник сообщества
Я думаю первого варианта для меня пока хватит.
Хочется понять алгоритм работы кода .
Ну тогда там нечего писать.
Можно простейшим вариантом:
1) читаем побайтно, пока не встретим к примеру символ "<"
2) встретив "<" читаем в буфер до ">" или по ограничению размера буфера для строки '<... "today-temp">'
ищем в буфере 'today-temp'
если не нашли - на п.п.1
если нашли - считываем следующие символы - это и будет температура.
 

pvvx

Активный участник сообщества
Код:
#include <ESP8266WiFi.h>
#include <WiFiClientSecure.h>

#include <myAP.h>
//char ssid[] = "";       // your network SSID (name)
//char password[] = "";  // your network key

WiFiClientSecure client;

void setup() {
  Serial.begin(115200);
  WiFi.mode(WIFI_STA);
  WiFi.disconnect();
  delay(100);
  Serial.print("Connecting Wifi: ");
  Serial.println(ssid);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    Serial.print(".");
    delay(500);
  }
  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  IPAddress ip = WiFi.localIP();
  Serial.println(ip);
}

char host[] = "sinoptik.com.ru";
char id_txt[] = "<p class=\"today-temp\">";
int tmp;

int get_tmp(void) {
  char buf[16];
  int i = 0;
  while (client.available()) {
    if (id_txt[i] == client.read()) {
      i++;
      if (i == sizeof(id_txt) - 1) {
        client.read((uint8_t *)buf, sizeof(buf) - 1);
        buf[sizeof(buf) - 1] = 0;
        tmp = atoi(buf);
        return 1;
      }
    }
    else i = 0;
  }
  return 0;
}

void loop() {
  if (client.connect(host, 443)) {
    Serial.println("Connected...");
    client.println("GET / HTTP/1.1");
    client.print("Host: "); client.println(host);
    client.println("User-Agent: arduino/1.0");
    client.println("");
    delay(1000);
    if (get_tmp()) {
      Serial.print("today-temp = ");
      Serial.println(tmp);
    }
    else Serial.println("Error!");
    client.stop();
  }
  // ....
  while(1) delay(10000);
}
Код:
Connecting Wifi: ****
.......
WiFi connected
IP address: 
192.168.1.225
Connected...
today-temp = 6
 
Спасибо большое. У меня тоже получилось , но правда в основном через if и if(string1.equals(string2)) . Но такое в приличном месте показывать нельзя.
И последний вопрос .
Если вводить sinoptik.com.ru - то коннектится.
А если на сайте выбираешь другой город и вставляешь в код строку с браузера , то уже коннектится не хочет .
sinoptik.com.ru/%D0%BF%D0%BE%D0%B3%D0%BE%D0%B4%D0%B0-%D0%BB%D0%BE%D0%BD%D0%B4%D0%BE%D0%BD
В чем может быть причина ? Или это не та строка ?
 

pvvx

Активный участник сообщества
Если вводить sinoptik.com.ru - то коннектится.
А если на сайте выбираешь другой город и вставляешь в код строку с браузера , то уже коннектится не хочет .
sinoptik.com.ru/%D0%BF%D0%BE%D0%B3%D0%BE%D0%B4%D0%B0-%D0%BB%D0%BE%D0%BD%D0%B4%D0%BE%D0%BD
В чем может быть причина ? Или это не та строка ?
Это вопрос к сайту. Какое они хотят оформление страниц такое и делают... Считывать значение температур со старниц, которые могут меняться каждый день как-то не очень. Там надо уже ИИ с распознаванием... :)
Более стабильно считывать с информеров SINOPTIK: Информер погоды, красивый погодный информер на сайт. Виджет погоды для сайта
 

Алексей.

Active member
Для сайта он отдает полтора килограмма html кода :)
Код:
curl -v -L 'https://sinoptik.com.ru/informers_js.php?lang=en&cities=100524901'
*   Trying 212.42.76.150...
* Connected to sinoptik.com.ru (212.42.76.150) port 443 (#0)
* found 148 certificates in /etc/ssl/certs/ca-certificates.crt
* found 597 certificates in /etc/ssl/certs
* ALPN, offering http/1.1
* SSL connection using TLS1.2 / ECDHE_RSA_AES_256_GCM_SHA384
*     server certificate verification OK
*     server certificate status verification SKIPPED
*     common name: sinoptik.uk (matched)
*     server certificate expiration date OK
*     server certificate activation date OK
*     certificate public key: RSA
*     certificate version: #3
*     subject: OU=Domain Control Validated,OU=PositiveSSL Multi-Domain,CN=sinoptik.uk
*     start date: Mon, 06 Nov 2017 00:00:00 GMT
*     expire date: Tue, 06 Nov 2018 23:59:59 GMT
*     issuer: C=GB,ST=Greater Manchester,L=Salford,O=COMODO CA Limited,CN=COMODO RSA Domain Validation Secure Server CA
*     compression: NULL
* ALPN, server accepted to use http/1.1
> GET /informers_js.php?lang=en&cities=100524901 HTTP/1.1
> Host: sinoptik.com.ru
> User-Agent: curl/7.47.0
> Accept: */*
>
< HTTP/1.1 200 OK
< Server: nginx
< Date: Thu, 26 Apr 2018 07:57:08 GMT
< Content-Type: application/json
< Transfer-Encoding: chunked
< Connection: keep-alive
< Set-Cookie: os=UNKNOWN; path=/
< X-Powered-By: PHP/5.5.38
< Expires: 0
< Cache-Control: must-revalidate, post-check=0, pre-check=0
< Pragma: no-store, no-cache, must-revalidate
< Vary: Accept-Encoding
< X-Server-By: sinfe1
<
var siCss=document.createElement('link');siCss.setAttribute('rel','stylesheet');siCss.setAttribute('type','text/css');siCss.setAttribute('href','//sinst.fwdcdn.com/css/informers2.css?v=1');document.getElementsByTagName('head')[0].appendChild(siCss);function siClickCount(){var siCount=document.createElement('script');siCount.setAttribute('type','text/javascript');siCount.setAttribute('src','//sinoptik.com.ru/click/informers/ru.html?rnd='+new Date().valueOf());document.getElementsByTagName('head')[0].appendChild(siCount);}function LoadInformer(data){if(document.getElementById('siHeader')){document.getElementById('siHeader').innerHTML=data.date};for(var i=0;i< data.body.length;i++){if(data.body[i]!=null){if(document.getElementById('siT'+i)){document.getElementById('siT'+i).innerHTML=data.body[i].temp};if(document.getElementById('weatherIco'+i)){document.getElementById('weatherIco'+i).className='weatherIco '+data.body[i].img};if(document.getElementById('vl'+i)){document.getElementById('vl'+i).innerHTML=data.body[* Connection #0 to host sinoptik.com.ru left intact
i].rh};if(document.getElementById('dav'+i)){document.getElementById('dav'+i).innerHTML=data.body[i].p};if(document.getElementById('wind'+i)){document.getElementById('wind'+i).innerHTML=data.body[i].ws};}}document.getElementById('SinoptikInformer').style.display='block';}LoadInformer( {date:'26.04.18, morning', body:[{"temp":"+11&deg;","wt":null,"ws":"4.8 , <span class=\"wind wind-S\" title=\"south\"><\/span>","p":"734 ","rh":"88%","img":"d430"}]} )
полезное из него только в самом конце
body:[{"temp":"+11&deg;","wt":null,"ws":"4.8 , <span class=\"wind wind-S\" title=\"south\"><\/span>","p":"734 ","rh":"88%","img":"d430"}]} )
 
Сверху Снизу