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

    Program pro generování 3D lidských postav MakeHuman (Wikipedie, GitHub) byl vydán ve verzi 1.3.0. Hlavní novinkou je výběr tvaru těla (body shapes).

    Ladislav Hagara | Komentářů: 3
    včera 23:11 | Bezpečnostní upozornění

    Intel vydal 41 upozornění na bezpečnostní chyby ve svých produktech. Současně vydal verzi 20240514 mikrokódů pro své procesory řešící INTEL-SA-01051, INTEL-SA-01052 a INTEL-SA-01036.

    Ladislav Hagara | Komentářů: 0
    včera 16:22 | IT novinky

    Společnost Raspberry Pi patřící nadaci Raspberry Pi chystá IPO a vstup na Londýnskou burzu.

    Ladislav Hagara | Komentářů: 0
    včera 13:22 | IT novinky

    Google na své vývojářské konferenci Google I/O 2024 představil řadu novinek. Keynote byl věnován umělé inteligenci (DeepMind, Gemini, Responsible AI).

    Ladislav Hagara | Komentářů: 1
    včera 12:33 | Bezpečnostní upozornění

    V Gitu bylo nalezeno 5 zranitelností. Opraveny jsou ve verzích 2.45.1, 2.44.1, 2.43.4, 2.42.2, 2.41.1, 2.40.2 a 2.39.4. Útočník může připravit repozitář tak, že při jeho klonování (git clone) může dojít ke spuštění libovolného kódu.

    Ladislav Hagara | Komentářů: 0
    včera 04:11 | IT novinky

    Virtualizační softwary VMware Workstation Pro a VMware Fusion Pro jsou nově pro osobní použití zdarma. Softwary VMware Workstation Player a VMware Fusion Player končí.

    Ladislav Hagara | Komentářů: 2
    včera 02:11 | Nová verze

    Linuxová distribuce Endless OS (Wikipedie) byla vydána ve verzi 6.0.0. Přehled novinek i s náhledy v příspěvku na blogu, poznámkách k vydání a také na YouTube.

    Ladislav Hagara | Komentářů: 0
    14.5. 15:44 | Nová verze

    Byl vydán Mozilla Firefox 126.0. Přehled novinek v poznámkách k vydání, poznámkách k vydání pro firmy a na stránce věnované vývojářům. Vylepšena byla funkce "Zkopírovat odkaz bez sledovacích prvků". Přidána byla podpora zstd (Zstandard). Řešeny jsou rovněž bezpečnostní chyby. Nový Firefox 126 je již k dispozici také na Flathubu a Snapcraftu.

    Ladislav Hagara | Komentářů: 0
    14.5. 15:22 | Nová verze

    Grafana (Wikipedie), tj. open source nástroj pro vizualizaci různých metrik a s ní související dotazování, upozorňování a lepší porozumění, byla vydána ve verzi 11.0. Přehled novinek v aktualizované dokumentaci.

    Ladislav Hagara | Komentářů: 0
    14.5. 14:55 | Nová verze

    Byla vydána nová verze 24.0 linuxové distribuce Manjaro (Wikipedie). Její kódové jméno je Wynsdey. Ke stažení je v edicích GNOME, KDE PLASMA a XFCE.

    Ladislav Hagara | Komentářů: 2
    Podle hypotézy Mrtvý Internet mj. tvoří většinu online interakcí boti.
     (74%)
     (5%)
     (10%)
     (10%)
    Celkem 283 hlasů
     Komentářů: 16, poslední 14.5. 11:05
    Rozcestník

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

    17.3.2020 17:12 Ogeen
    Parsování dat z webové stránky s javascriptem
    Přečteno: 671×
    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.2020 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.2020 17:47 jiwopene | skóre: 31 | blog: Od každého trochu…
    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.2020 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.2020 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.2020 11:33 Gréta | skóre: 36 | blog: Grétin blogísek | 🇮🇱==❤️ , 🇵🇸==💩 , 🇪🇺==☭
    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

    18.3.2020 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.2020 13:13 Gréta | skóre: 36 | blog: Grétin blogísek | 🇮🇱==❤️ , 🇵🇸==💩 , 🇪🇺==☭
    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 :'(

    18.3.2020 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.2020 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.2020 17:19 Gréta | skóre: 36 | blog: Grétin blogísek | 🇮🇱==❤️ , 🇵🇸==💩 , 🇪🇺==☭
    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))
    
    
    18.3.2020 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.2020 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.2020 22:18 Gréta | skóre: 36 | blog: Grétin blogísek | 🇮🇱==❤️ , 🇵🇸==💩 , 🇪🇺==☭
    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

    20.3.2020 15:22 Ogeen
    Rozbalit Rozbalit vše Re: Parsování dat z webové stránky s javascriptem
    Ok. Díky za komentář.
    19.3.2020 10:57 Jouda
    Rozbalit Rozbalit vše Re: Parsování dat z webové stránky s javascriptem
    Dalsi moznost je pouzit XPath.
    18.3.2020 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.2020 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.2020 13:44 Josef Kufner | skóre: 70
    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.2020 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.2020 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.