abclinuxu.cz AbcLinuxu.cz itbiz.cz ITBiz.cz HDmag.cz HDmag.cz abcprace.cz AbcPráce.cz
AbcLinuxu hledá autory!
Inzerujte na AbcPráce.cz od 950 Kč
Rozšířené hledání
×
dnes 18:22 | Nová verze

Byla vydána finální beta verze Ubuntu 20.04 LTS s kódovým názvem Focal Fossa. Přehled novinek v poznámkách k vydání. Dle plánu by Ubuntu 20.04 mělo vyjít 23. dubna 2020.

Ladislav Hagara | Komentářů: 0
dnes 17:22 | Nová verze

Vyšel XCP-ng 8.1 (seznam změn), alternativní sestavení Citrix Hypervisor (dříve XenServer), tedy serverová distribuce hypervizoru Xen (4.13), toolstacku XAPI a systému CentOS v privilegované doméně. XCP-ng na rozdíl od bezplatné verze Citrix Hypervisoru nemá četná omezení funkcionality, vývojáři ale nabízejí i komerční podporu. Novinkou (zatím) pouze v XCP-ng je možnost zálohovat VM včetně aktuálního stavu jejich paměti; funkce je integrována také v administračním nástroji Xen Orchestra.

Fluttershy, yay! | Komentářů: 0
včera 17:55 | Nová verze

Byl vydán LineageOS ve verzi 17.1. LineageOS (Wikipedie) je svobodný operační systém pro chytré telefony, tablety a set-top boxy založený na Androidu. Jedná se o nástupce CyanogenModu. LineageOS 17.1 je založený na Androidu 10.

Ladislav Hagara | Komentářů: 6
včera 17:22 | Zajímavý projekt

Lukasz Erecinski na blogu Pine64 oznámil možnost předobjednání telefonu PinePhone v edici UBports Community Edition. Telefon bude mít speciální kryt s logem a nápisem UBports Edition. Základní deska bude podle nového schématu (v1.2) vylepšená podle zpětné vazby od majitelů BraveHeart edice. Bude mít FCC i CE certifikace.

joejoe | Komentářů: 3
včera 15:33 | IT novinky

Společnost Cloudflare před dvěma lety spustila DNS resolver 1.1.1.1. Včera spustila 1.1.1.1 pro rodiny aneb nové resolvery 1.1.1.2 (2606:4700:4700::1112) a 1.1.1.3 (2606:4700:4700::1113) blokující stránky s malwarem a obsahem pro dospělé. Dnes se omluvila, že nechtěně blokovala také LGBTQIA+ stránky.

Ladislav Hagara | Komentářů: 29
včera 14:55 | Nová verze

Společnost Red Hat oznámila vydání Red Hat Enterprise Linuxu 7.8, který přináší vedle nových vlastností a oprav chyb také aktualizaci ovladačů a předběžné ukázky budoucích technologií. Podrobnosti v poznámkách k vydání.

Ladislav Hagara | Komentářů: 0
včera 14:33 | Nová verze

V pondělí vyšel Linux 5.6. Dnes vyšla jeho 2. opravná verze 5.6.2 (git). Opravena byla mimo jiné diskutovaná chyba v ovladači iwlwifi.

Ladislav Hagara | Komentářů: 0
1.4. 19:55 | Nová verze

Po dvou letech od vydání verze 3.0 byla vydána nová major verze 4.0 nástrojů LXC, LXD a LXCFS pro kontejnerovou virtualizaci LXC (LinuX Containers). Jedná se o verzi s dlouhodobou podporou (LTS). Ta končí v červnu 2025. Přehled novinek v jednotlivých oznámeních o vydání: LXC, LXD a LXCFS.

Ladislav Hagara | Komentářů: 3
1.4. 16:11 | Humor

Řada firem své letošní již připravené aprílové žertíky kvůli SARS-CoV-2 a COVID-19 nezveřejnila. Přehled zveřejněných například na April Fools' Day On The Web. Na CoinMarketCapu byla přidána nová kryptoměna: toaleťáky. Ve hře World of Tanks jsou vylepšené tanky, v PUBG nový herní mód Fantasy Battle Royale, …

Ladislav Hagara | Komentářů: 3
1.4. 15:22 | Humor

Komunity KDE a GNOME, které doposud vyvíjely příslušná desktopová prostředí, se rozhodly přestat tříštit síly a představují společný projekt KNOME, který nabídne konfigurovatelnost GNOME a jednoduchost KDE v jednom balíčku. Staví na technologiích QTK3 a Kutter.

Fluttershy, yay! | Komentářů: 26
Chodíte do práce?
 (25%)
 (1%)
 (6%)
 (1%)
 (49%)
 (12%)
 (5%)
Celkem 77 hlasů
 Komentářů: 4, poslední včera 14:20
Rozcestník

www.AutoDoc.Cz

Dotaz: Parsování dat z webové stránky s javascriptem

17.3. 17:12 Ogeen
Parsování dat z webové stránky s javascriptem
Přečteno: 567×
Příloha:
Ahoj,

potřebuju napsat plugin pro check_mk, který bude kontrolovat zda se ústředna OXO od Alcatelu úspěšně připojila k SIP Trunku Providera.

Bohužel jediná možnost, jak vyčíst aktuální status připojení k SIP Trunku je přes stránku ve webovém rozhraní. Já jsem tedy aspoň žádnou jinou možnost nenašel.

Relevatní část stránky vypadá takto: viz. příloha

Tabulka je bonužel generovaná javascriptem, takže pro její získání nemůžu použít curl a podobné. Standarní http_check nagiosu to však zvládne.

Počet SIP Trunků může být různý. Zkusil jsem slepit jednoduchý skript v Pythonu, který by mi ze stránky vytáhnul odpovídající tabulku a vrátil relevantní data ve formátu, který bych mohl použít pro vyhodnocení stavu jednotlivých SIP Trunků. Např:

PRD, PDDI, STATUS
192.168.0.25, somestring, REGISTRATION SUCCESSFUL
our.domain.de, somestring, REGISTRATION FAILED
S takovýmhle polem bych už si pak snad dokázal poradit a napsat plugin, který by pro každý SIP Trunk vyhodnotil jeho stav a vrátil tuto hodnotu check_mk. Bohužel by mi to samotnému trvalo dost dlouho.

Dokázal by mně někdo nasměrovat k elegantnímu řešení? Díky!

Odpovědi

17.3. 17:17 Jouda
Rozbalit Rozbalit vše Re: Parsování dat z webové stránky s javascriptem
Urcite by slo pouzit sluzbu jako je treba Apify, ale je to "kanon na vrabce".
17.3. 17:47 jiwopene | skóre: 20
Rozbalit Rozbalit vše Re: Parsování dat z webové stránky s javascriptem
Koukněte se na to, zda ten JavaScript nebere data pomocí nějakého použitelného API. Např. ve Firefoxu to je ve vývojářských nástrojích na záložce „Network“. Většinou to zobrazí filtry XHR, WS nebo JS.

JavaScriptem generované stránky jsou zpravidla jednodušší na zpracování, protože nějaké strojově čitelné API mezi serverem a klientem (JS ve stránce) je.
.sig virus 3.2_cz: Prosím, okopírujte tento text do vaší patičky.
17.3. 22:02 Ogeen
Rozbalit Rozbalit vše Re: Parsování dat z webové stránky s javascriptem
Díky za odpověď.

Celá url vypadá takto:
https://192.168.3.200/services/webapp/monitor/sip_i.php?sip_i=regstatus
A tahá to jen několik js souborů:
sip_i.js
jquery.js
bootstrap.min.js
sorttable.js
jquery.quicksearch.js

Nás nejspíš zajímá sip_i.js:

var dataTable;

function init()
{
        dataTable = document.getElementById("datatable");
        var aCheckBoxes = document.getElementsByName("checkboxes");
        dataTable.CheckBoxes = aCheckBoxes;
}

function selectAllRows(x)
{
        var aCheckBoxes = dataTable.CheckBoxes;
        var bChecked = false; 

        if(x.id == 'clearall' || x.id == 'checkall')
        {
                bChecked = (x.id == 'clearall') ? false : true;
        }
        var aRows = dataTable.tBodies[0].rows;

        // nRows is the index of the last checkbox
        // warning : remove the title line

        var nRows = aRows.length-2;

        for(var i=nRows;i>=0;i--)
        {
                aCheckBoxes[i].checked = bChecked;
        }
}

function deleteSelected()
{
        var aRows = dataTable.tBodies[0].rows;
        var nRows = aRows.length-2;
        var parm="";
        var aCheckBoxes = dataTable.CheckBoxes;

        for(var i=nRows;i>=0;i--)
        {

                if (aCheckBoxes[i].checked)
                {
                        if (parm != "")
                                parm+=" "
                        parm+=aCheckBoxes[i].value;
                }
        }
        document.getElementById("theParam").value = parm ;
        document.getElementById("theForm").submit();

}
Já z toho bohužel nedokážu na první pohled vyčíst, jestli tam nějaké použitelné api je.
17.3. 23:56 Ogeen
Rozbalit Rozbalit vše Re: Parsování dat z webové stránky s javascriptem
Tak po chvíli hraní s chrome, debugerem a breakpointy jsem zjistil, že celá zmiňovaná tabulka je nejspíš vygenerovaná zavoláním tohoto jednoho řádku:

dataTable = document.getElementById("datatable");
Upravil jsem soubor sip_i.js, tak, že v něm zbylo pouze toto:
var dataTable;

function init()
{
        dataTable = document.getElementById("datatable");
}
Uložil vše do overrides a stránka se posléze načetla v podstatě normálně a zobrazila i tabulku s informaci o SIP Trunku.
Gréta avatar 18.3. 11:33 Gréta | skóre: 19 | blog: Grétin blogísek | Stockholm
Rozbalit Rozbalit vše Re: Parsování dat z webové stránky s javascriptem

nóóóóóó vygenerovaná ne :O :O ;D ten řádeček kódu dělá že se v html dokumentu najde element co má parametr id nastavenej na 'datatable' a tan se uloží do proměný dataTable ;D

zisti z kterýho html souboru seto volá a tam si najdi tu tabluku a tu asi jako možná pude parsovat pythonem :O ;D

✊3 things to learn in skiing: •how to put on your skis •how to slide downhill •how to walk along the hospital corridor✊
18.3. 12:16 Ogeen
Rozbalit Rozbalit vše Re: Parsování dat z webové stránky s javascriptem

Díky, svatá Gréto! :) Jediný element s nějakým parametrem id je tento:

ífrejm width="100%" frameborder="0" src="./blank.html" name="content" id="content" onload="javascript:resizeIframe(this);"> ífrejm

A to bohužel není to co bysme potřebovali. Pak už jsem tam našel jen dvě tabulky s class="dataTable, ale to mi taky nepomůže. Kód stránky po načtení vypadá takto:

https://pastebin.com/X89nPLzy

Vidím tam, že se načte skript:

SRC="./js/sip_i.js"

A o kus níže se zavolá funkce init() z tohohle skriptu:

init();
Díky!
Gréta avatar 18.3. 13:13 Gréta | skóre: 19 | blog: Grétin blogísek | Stockholm
Rozbalit Rozbalit vše Re: Parsování dat z webové stránky s javascriptem

hhhmmmmm celý je to takový divný :O :'( to je celej ten sip_i.js co sems dával?? tam seasi jako jenom nějak čaruje s checkboxama :'( fakt ty data nenačítá nějakej php skript strčenej v místě tý tabulky v tom html dokumentu?? jestli mužeš tak sem hoď jak ten dokument z pastebin vypadá bez zapnutýho js třeba staženej wgetem

ještě sem dej možná tamto sorttable.js třeba to nedělá jenom řazení nevim

podezírám podobně pomenovanej skript sip_i.php že se někde asi bude volat ale jako hádám :'(

✊3 things to learn in skiing: •how to put on your skis •how to slide downhill •how to walk along the hospital corridor✊
18.3. 13:46 Ogeen
Rozbalit Rozbalit vše Re: Parsování dat z webové stránky s javascriptem
Ok. Tak asi budu za úplnýho trotla, ale třeba se z toho poučí někdo další.

Pokud tuhle url zavolám s lomítkem na konci:
https://192.168.2.100/services/webapp/monitor/sip_i.php?sip_i=regstatus/

Tak dostanu stránku bez tabulky SIP Trunků. A tuhle chybu jsem přesně udělal v mám pythoním skriptu.

Pokud zmíněnou url zavolám bez lomítka na konci, tami mi curl, wget i python vrátí stránku s tabulkou. Takže celá hypotéza s javascriptem byla mylná. sigh

Tím se ovšem dostáváme k původní otázce, jak příslušnou tabulku, která může mít teoreticky neomezený počet řádek, rozsekat v pythonu do nějakého použitelného tvaru. Prakticky těch řádek moc nebude.
18.3. 14:52 panika
Rozbalit Rozbalit vše Re: Parsování dat z webové stránky s javascriptem
https://www.crummy.com/software/BeautifulSoup/bs4/doc/
Gréta avatar 18.3. 17:19 Gréta | skóre: 19 | blog: Grétin blogísek | Stockholm
Rozbalit Rozbalit vše Re: Parsování dat z webové stránky s javascriptem

fakt si to jako dobře nakopíroval ten html kód?? tam tabulka neni uzavřená :O :O

todleto by ti mohlo fungovat i tak ;D

from bs4 import BeautifulSoup
import urllib3

http = urllib3.PoolManager()

url = 'https://192.168.2.100/services/webapp/monitor/sip_i.php?sip_i=regstatus'
response = http.request('GET', url)

soup = BeautifulSoup(response.data,"html.parser")

counter=0
#maj tam chybu tag table neni uzavřenej a nemužeme rozumě skákat po tabulkách fakt si to dobře nakopíroval?? :O :O
#proto sem šáhla po těch 'td'
counter=0
PRD=""  # :D :D :D :D
PDDI=""
STATUS=""

rows=[]

#pro všechny td tagy v html až jako na ten poslední
#poslední je nějaká kravinka
for td in soup.find_all("td")[:-1]:
    if counter==0:
        PRD=td.find('b').text.split('-')[1].strip()
        counter+=1
    elif counter==1:
        if not "Public DDI" in td.text:
            raise IndexError('sem jako cekala na indexu 1 hodnotu Public DDI a mam tam '+td.text+'!!!! :O :O')
        counter+=1
    elif counter==2:
        if not "STATUS" in td.text:
            raise IndexError('sem jako cekala na indexu 2 hodnotu STATUS a mam tam '+td.text+'!!!! :O :O')
        counter+=1
    elif counter==3:
        PDDI=td.text
        counter+=1
    elif counter==4:
        STATUS=td.text.strip()
        
        #udělali jsme kolečko jedný tabulky uložíme řádek napotom
        counter=0
        rows.append({'PRD': PRD,'PDDI': PDDI,'STATUS': STATUS})
    else:
        raise IndexError('jako neco je hoooooooooooooooodne spatne protoze index neni v intervalu 0-4!!!! :O :O')
    
for row in rows:
    print("PRD: {PRD} PDDI: {PDDI} STATUS: {STATUS}".format(**row))

✊3 things to learn in skiing: •how to put on your skis •how to slide downhill •how to walk along the hospital corridor✊
18.3. 20:52 Ogeen
Rozbalit Rozbalit vše Re: Parsování dat z webové stránky s javascriptem
Ano, opravdu sem to zkopíroval dobře. Nevim co za matroš u toho ti Frantíci hulili, ale za střízliva to rozhodně nepsali. :) Neuzavřená tabulka mě vůbec nepřekvapuje.

Díky za pomoc!
18.3. 23:19 Ogeen
Rozbalit Rozbalit vše Re: Parsování dat z webové stránky s javascriptem

Tak po pár menší úpravách mi to funguje. Bylo potřeba přidat autentizaci a ignorovat chybu certifikátu. A split v prvním td bylo potřeba udělat pomocí mezery, protože string za pomlčkou může pomlčku obsahovat:

#!/usr/bin/env python3

# importing the libraries
import requests
from urllib3.exceptions import InsecureRequestWarning
from bs4 import BeautifulSoup

# Suppress only the single warning from urllib3 needed.
requests.packages.urllib3.disable_warnings(category=InsecureRequestWarning)

# Define variables
url = "https://192.168.2.100/services/webapp/monitor/sip_i.php?sip_i=regstatus"
user = 'user'
passwd = 'secret'

# Make a GET request to fetch the raw HTML content
response = requests.get(url, auth=(user, passwd), verify=False)

# Parse the html content
soup = BeautifulSoup(response.text, "html.parser")

counter=0
counter=0
PRD=""
PDDI=""
STATUS=""

rows=[]

for td in soup.find_all("td")[:-1]:
    if counter==0:
        PRD=td.find('b').text.split(' ')[4].strip()
        counter+=1
    elif counter==1:
        if not "Public DDI" in td.text:
            raise IndexError('Expected value "Public DDI" but got '+td.text+'')
        counter+=1
    elif counter==2:
        if not "STATUS" in td.text:
            raise IndexError('Expected value "STATUS" but got '+td.text+'')
        counter+=1
    elif counter==3:
        PDDI=td.text
        counter+=1
    elif counter==4:
        STATUS=td.text.strip()

        # First table is ready. We save the row for next time.
        counter=0
        rows.append({'PRD': PRD,'PDDI': PDDI,'STATUS': STATUS})
    else:
        raise IndexError('Critical Error. Index is not within interval 0-4')

for row in rows:
    print("PRD: {PRD} PDDI: {PDDI} STATUS: {STATUS}".format(**row))
Teď z toho ještě zbastlit check pro check_mk, ale s tim už si nějak poradim. Díky všem.
Gréta avatar 19.3. 22:18 Gréta | skóre: 19 | blog: Grétin blogísek | Stockholm
Rozbalit Rozbalit vše Re: Parsování dat z webové stránky s javascriptem

mužeš udělat split jenom prvním výskytem znaku/stringu uplně jednoduše takhle text.split('-',1)

taky je dobrý nedělat takovýdle krkolomný jednořádkový šílenosti jakože td.find('b').text.split('-',1)[1].strip()protože každej z těch kroků muže selhat třeba to jako nenajde tag b a vrátí to None b nemusí mit text za pomlčkou už nic nemusí bejt a tak. lepšejší je to mit rozdělený na jednotlivý kroky a ty případný chyby hlídat jim moc nevěřim když neuměj ani uzavřit tabulku :O ;D joa že tam je proměná counter dvakrát to je samo že navíc stačí ho mit jenom jednou ;D

nóóó sem trošku čuňačila aby to jako bylo rychle hotový :O :O :D ;D

✊3 things to learn in skiing: •how to put on your skis •how to slide downhill •how to walk along the hospital corridor✊
20.3. 15:22 Ogeen
Rozbalit Rozbalit vše Re: Parsování dat z webové stránky s javascriptem
Ok. Díky za komentář.
19.3. 10:57 Jouda
Rozbalit Rozbalit vše Re: Parsování dat z webové stránky s javascriptem
Dalsi moznost je pouzit XPath.
18.3. 10:41 robac
Rozbalit Rozbalit vše Re: Parsování dat z webové stránky s javascriptem
Alcatel neznám a možná by také, když už se na něco ptáte, neškodilo přihodit typ zařízení a (hlavně) firmware a informace o licenci (pokud existuje více licenčních modelů). Každopádně vsadím boty, že to API má...
18.3. 11:29 Ogeen
Rozbalit Rozbalit vše Re: Parsování dat z webové stránky s javascriptem
Jedná se o:
OXO Connect Rel. 3.2

cpu name:	PowerCPU
Software: 	ONEDE032/039.001
Linux kernel: 	Linux version 2.6.29.6-rt23-030.001
O licencích jsem nic nenašel.

Nějaké API to určitě má, zkusim něco najít na jejich business portálu. Bohužel moje dosavadní zkušenost s alcatelem by se dala popsat tak, že obchodní oddělení je mnohem lepší než oddělení vývoje. Můj čistě osobní dojem z jejich produktů je, že to je nepřehledný nepořádek.
Josef Kufner avatar 18.3. 13:44 Josef Kufner | skóre: 69
Rozbalit Rozbalit vše Re: Parsování dat z webové stránky s javascriptem
Otevři si ten tab se síťovým provozem a koukni se, jaké HTTP požadavky ta stránka posílá. Ten, který bude přinášet požadovaná data pak vykopíruj jako volání curl a dej si to do skriptu. Možná budeš muset ještě pořešit přihlašování.
Hello world ! Segmentation fault (core dumped)
18.3. 13:47 Ogeen
Rozbalit Rozbalit vše Re: Parsování dat z webové stránky s javascriptem
Problém byl jinde. Viz odpověď na Grétin post.
23.3. 13:28 Ogeen
Rozbalit Rozbalit vše Re: Parsování dat z webové stránky s javascriptem
Kdyby to někoho zajímalo, tak tady je varianta skriptu, která očekává 4 parametry a vrací už validní odpověď pro check_mk.

Nejsem žádný programátor, tak budu vděčný za návrhy na zjednodušení apod.

#!/usr/bin/env python3

# importing the libraries
import sys, getopt
import requests
import re
from urllib3.exceptions import InsecureRequestWarning
from bs4 import BeautifulSoup

# Suppress only the single warning from urllib3 needed.
requests.packages.urllib3.disable_warnings(category=InsecureRequestWarning)

#def main (argv):
url = ''
user = ''
passwd = ''
hostname = ''
prd = ''

# Get full command-line arguments
full_cmd_arguments = sys.argv

# Keep all but the first
argument_list = full_cmd_arguments[1:]

short_options = "hu:p:H:P:"
long_options = ["username=","password=","hostname=","publicregistrationdomain"]

def usage():
    print('check-sip-trunk.py -u <username> -p <password> -H <hostname> -P <publicregistrationdomain>')

try:
    arguments, values = getopt.getopt(argument_list, short_options, long_options)
except getopt.GetoptError as err:
    print (str(err))
    usage()
    sys.exit(2)

if not arguments:
  usage()
  sys.exit(2)

for opt, arg in arguments:
    if opt == '-h':
        usage()
        sys.exit()
    elif opt in ("-u", "--username"):
        user = arg
    elif opt in ("-p", "--password"):
        passwd = arg
    elif opt in ("-H", "--hostname"):
        hostname = arg
        url = f"https://{hostname}/services/webapp/monitor/sip_i.php?sip_i=regstatus"
    elif opt in ("-P", "--publicregistrationdomain"):
        prd = arg

# Make a GET request to fetch the raw HTML content
response = requests.get(url, auth=(user, passwd), verify=False)

# Parse the html content
soup = BeautifulSoup(response.text, "lxml")

counter=0
PRD=""
PDDI=""
STATUS=""

rows=[]

for td in soup.find_all("td")[:-1]:
    if counter==0:
        PRD=td.find('b')
        if PRD is not None:
            PRD=PRD.text.split('-',1)[1].strip()
            counter+=1
        else:
            raise IndexError('Tag containing Public Registration Domain not found')
    elif counter==1:
        if not "Public DDI" in td.text:
            raise IndexError('Expected value "Public DDI" but got '+td.text+'')
        counter+=1
    elif counter==2:
        if not "STATUS" in td.text:
            raise IndexError('Expected value "STATUS" but got '+td.text+'')
        counter+=1
    elif counter==3:
        PDDI=td.text
        counter+=1
    elif counter==4:
        STATUS=td.text.strip()

        counter=0
        if STATUS=="REGISTRATION SUCCESSFUL":
            trunkstatus = "0 SIP-TRUNK - OK: Public Registration Domain - "+PRD+", Public DDI - "+PDDI+", Status - "+STATUS
            rows.append(trunkstatus)
        elif STATUS=="REGISTRATION FAILED":
            trunkstatus = "2 SIP-TRUNK - CRITICAL: Public Registration Domain - "+PRD+", Public DDI - "+PDDI+", Status - "+STATUS
            rows.append(trunkstatus)
        else:
            trunkstatus = "3 SIP-TRUNK - UNKNOWN: Public Registration Domain - "+PRD+", Public DDI - "+PDDI+", Status - "+STATUS
            rows.append(trunkstatus)
    else:
        raise IndexError('Critical Error. Index is not within interval 0-4')

for item in rows:
    if re.search(rf"\b{prd}\b",item):
        print(item)
        sys.exit()
    else:
        print("Public Registration Domain \""+prd+"\" does not exist.")
        sys.exit(2)

Založit nové vláknoNahoru

Tiskni Sdílej: Linkuj Jaggni to Vybrali.sme.sk Google Del.icio.us Facebook

ISSN 1214-1267   www.czech-server.cz
© 1999-2015 Nitemedia s. r. o. Všechna práva vyhrazena.