🔪 Data scraping / Skrobanie danych ze stron

Data scraping / Skrobanie danych

:hocho:
po angielsku chyba lepiej brzmi :wink:

Pokażę jak w bardzo łatwy spsób można pobierać dane ze stron bo np. nie ma api a wiemy, że jest jakaś informacja na stronie i chcemy ją mieć w HA.
Scraping nie jest do końca legalny… omijamy reklamy itd… robimy to czysto edukacyjnie :slight_smile:

Zrobimy to na bramce w JavaScript - NodeJS:

Załużmy, że chcemy pobrać kurs miedzi ze strony bankier.pl

Selektor css

w tym celu otweiramy w przeglądarce źródło strony i lokalizujemy element z ceną:

jak widać jest to div.profilLast

Program w nodejs

Teraz napiszemy programik który będzie te dane skrobał (echh) ze strony cenę miedzi.
W konsoli przechodzimy do AIS i tworzymy folder programy

cd ~/AIS
mkdir programy
cd programy

dodajemy plik miedz.js

nano miedz.js

z takim kodem:

const axios = require('axios');
const jsdom = require('jsdom');
const {JSDOM} = jsdom;

(async () => {
 const html = await axios.get('https://www.bankier.pl/inwestowanie/profile/quote.html?symbol=MIEDZ');
 const dom = new JSDOM(html.data);

 const cena = dom.window.document.querySelector('div.profilLast');

 if (cena) {
   console.log(cena.textContent)
 }
})();

zapisujemy plik, instalujemy 2 biblioteki:

npm install axios
npm install jsdom

teraz możemy już wywołać nasz program wpisując w konsoli:

node miedz.js 

Pomocnik w aplikacji

dodajemy pomocnika w aplikacji - to w nim będziemy zpisywali cenę miedzi

kopujemy identyfikator encji nowego pomocnika

i dodajemy go na stronę w aplikacji

Wywołanie programu z usługi

service: ais_shell_command.execute_command
data:
  command: node ~/AIS/programy/miedz.js
  entity_id: input_text.cena_miedzi

Automatyzacja

To już wiadomo - możemy wywołać uslugę z automatyzacji i sprawdzać cenę codziennie automatycznie.

:warning: Data scraping nie jest legalnym sposobem na dostęp do danych i dlatego ten post ma charakter czysto edukacyjny - żeby pokazać jak technicznie działa skrobanie danych ze stron.

5 polubień

Bardzo dziękuję za przykład. Edukacja trwa :wink:

O ile w konsoli otrzymuję prawidłowy wynik zeskrobanej ceny miedzi,
obraz

o tyle w HA jest jakiś kwiatek przy karcie encji.

W narzędziach deweloperskich podobnie:

Kod \xc2\xa0 w kodowaniu UTF-8 to tzw. niełamliwa spacja. trzeba by to odfiltrować :slight_smile:

1 polubienie

Tu jest trochę więcej śmieci:

  1. b’…’ - to raczej jest dodane przez serwis Jolki więc tego nie naprawisz
  2. \xx - można obejść regexem który kasuje non-ASCI znaki
  3. \n - koniec linii odczytany przez serwis Jolki i tam chyba powinien być ogarnięty, ewentualnie można napisać np. process.stdout.write(cena.textContent); zamiast console.log(cena.textContent)

Tylko jak to jest, że u @jolka jest czysty wynik a u mnie śmieci? Nie jestem programistą ale ciekawi mnie skąd taka różnica?

b’xxxx’ to klasa typu bytes z Python:

>>> text = b"9\xc2\xa0748,25 USD/tona\n"
>>> type(text)
<class 'bytes'>
>>> print(text)
b'9\xc2\xa0748,25 USD/tona\n'
>>> print(text.decode('UTF-8'))
9 748,25 USD/tona

po metodzie decode() w Phyton na print() mamy już bez “farfocli” :slight_smile:

Witam .
A czy ktoś może znalazł by czas żeby łopatologicznie wyłożyć jak zrobić takie pobieranie danych w przypadku jeżeli trzeba się zalogować na stronę i dopiero pobrać wyświetlane dane.

1 polubienie

Jeżeli strona do scrapingu jest prosta można skorzystać z oficjalnej integracji Scrape - Home Assistant, jest też możliwość autentykacji (podania loginu i hasła). Przy konieczności logowania do strony bardzo często można skorzystać z RESTful - Home Assistant.

Cześć, może pomógłby mi ktoś w ogarnięciu odczytu danych z mojego invertera pv ze strony foxesscloud.com chodzi dokładnie o dwa odczyty tzn: bieżąca produkcja i chwilowa moc .
Na stronę trzeba się oczywiście logować,



Fox Cloud API Protocol.pdf (451,0 KB)

Scraping tutaj nie ma sensu bo masz API, tylko musisz je skonfigurować.
Na dodatek jest opcja z MQTT więc “dzień dobry XXI wiek”

1 polubienie

Fajnie… Tylko kurka jak to osiągnąć?

widzę że jest integracja custom_components:
GitHub - macxq/foxess-ha: Home Assistant & FoxESS integration (cdnweb.icu)
ale faktycznie jak jest możliwość przez MQTT to najlepsze rozwiązanie, zacznij od ustawienia tego:


gdzie “Broker Addres” to adres ip twojej bramki

potem wykorzystując MQTT Explorer zobacz czy spływają jakieś dane po MQTT

1 polubienie

Może załóż nowy temat, jak zainstalować niestandardowy komponent masz opisane na forum…

@Tomasz - :+1:
może ten link z instrukcją będzie bardziej czytelny (ta sama integracja).

1 polubienie


powiedz co to jest?
masz to gdzieś w ustawieniach invertera a może w chmurze foxesscloud.com?
ja to tak rozumiem, że gdzieś w ustawieniach invertera wpisujesz adres swojego serwera mqtt czyli twojej bramki i wtedy bramka wykrywa sensory z invertera, coś na zasadzie jak z Iot link

Zacznij od przeczytania lektury aby zrozumieć jak działa MQTT:

Postaraj się zrozumieć i załóż osobny temat, to w nim Ci pomożemy. Szoka robić off-topic.

1 polubienie

Dobra, jak przetrawię tę wszystkie informacje i się trochę w tym ogarnę to założę nowy temat i tam będę drążył go dalej. Na tą chwilę podziękować wam muszę za pomoc!

faktycznie zwracamy obiekt w bajtach a nie tekst

image

zwraca

image

w python żeby przerobić obiekt w bajtach na string trzeba zrobić decode("utf-8")
trzeba dopisać coś takiego w pliku integracji ais_shell_command który jest na bramce

Poprawimy to w kolejnym wydaniu i opiszemy dokładniej usługę execute_command bo ona może mieć więcej parametrów (dotychczas używaliśmy ją tylko wewnętrznie) i może się to komuś przydać.

service: ais_shell_command.execute_command
data:
  command: echo "123 EUR"
  entity_id: input_text.cena_miedzi
  friendly_name: Aktualna cena miedzi
  icon: mdi:cash-100

ważne żeby zrozumieć działanie:


PS

Oczywiście można to zrobić w inny sposób, np. przez “asynchroniczny interfejs plikowy”. Czyli tak:

  1. Nasz program (w dowolnym języku który jest na bramce), robi jakąś “magię” i zapisuje wynik do pliku ~/AIS/programy/sensor1.txt

np. powyższy program który napisaliśmy w nodejs
możemy przekirować wyjście do pliku a nie bezpośrednio do encji w aplikacji, coś takiego

service: ais_shell_command.execute_command
data:
  command: node ~/AIS/programy/miedz.js > ~/AIS/programy/sensor1.txt

po wywołaniu takiej usługi

możemy sprawdzić w konsoli efekt:

cat ~/AIS/programy/sensor1.txt

image

  1. Dodajemy w AIS/HA sensor który zaczytuje dane z pliku
sensor:
  - platform: file
    file_path: ~/AIS/programy/sensor1.txt

Wszystko się dzieje asynchronicznie, nikt na nikogo nie czeka.

W efekcie mamy dane w encji nowego sensora, o te dane możemy pytać asystenta głosowo komendą:

  • status ...
  • jaka jest ...
  • jaki jest ...
3 polubienia