Jak uložit data do 2D pole typu 'list' – Python – Fórum – Programujte.com
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu

Jak uložit data do 2D pole typu 'list' – Python – Fórum – Programujte.comJak uložit data do 2D pole typu 'list' – Python – Fórum – Programujte.com

 

otula0
Duch
25. 9. 2023   #1
-
0
-

Ahoj, potřeboval bych poradit jakožto naprostý zoufalý začátečník.

Máme k zápočtu udělat jednoduchý program v Pythonu, který načte odněkud externí data a nějak s nimi pracuje v GUI. Vymyslel jsem, že udělám aplikaci, kde si z rozbalovacího menu vyberu krajské město vypíšou se mi k němu data o počasí ze serveru in-pocasi.cz.

Data ze stránky získám pomocí <code>BeautifulSoup</code>. Načtu je v cyklu do pole typu 'list' a v dalším cyklu je vypíšu. Když udělám pole jednorozměrné, všechno funguje, až na to, že když na stránce některý údaj chybí, tak nezískám prázdnou hodnotu, ale hodnota mi úplně chybí, což mi rozhodí přiřazení dat.

Zkusil jsem tedy kontrolovat, zda jsou data dostupná, a výsledky ukládat do dvourozměrného pole, abych věděl, co za hodnoty v poli mám. Ale když to udělám, přestane mi fungovat načítání textového obsahu z html pomocí <code>.text</code>. Trávím nad tím celý večer a netuším, jak na to...

Pokud byste mi poradili, jak to opravit případně napsat úplně jinak, byl bych rád. V následujícím kódu neřeším GUI, takže případný výběr města se udělá překomentováním url

from bs4 import BeautifulSoup
import requests
# získám html
url = 'https://www.in-pocasi.cz/aktualni-pocasi/olomouc/'
#url = 'https://www.in-pocasi.cz/aktualni-pocasi/brno_k/'
url_get = requests.get(url)
soup = BeautifulSoup(url_get.content, 'lxml')

#seznam údajů, které chci ze stránky vycucnout do 'mytds'
seznam = ["Čas měření", "Teplota", "Vítr", "Vlhkost", "Tlak", "Srážky dnes", "Změna teploty (30 min)", "Teplota před 24 hodinami", "Rosný bod"]
mytds = [] #typ list

# funkční verze, ale problematicky (funguje jen tehdy, když stránka obsahuje všechna data,
# například olomouc. Ale pokud se url přehodí na brno_k, chybí tam údaje a problém je na světě,
# protože se nenalezené záznamy vynechají a všechno se rozjede)

# načtení jednorozměrného seznamu
'''
for i in range(9):
    data = soup.find_all("td", {"data-title": seznam[i]})
    mytds.extend(data)

# vypsání seznamu
for i in range(len(mytds)):
    txt = seznam[i]+": "+mytds[i].text
    print(txt)
'''
    
# nefunkční verze, která by měla ukládat jen ta data, která jsou dostupná

for i in range(9):
    data = soup.find_all("td", {"data-title": seznam[i]})
    # tady ke každému 'řádku' v mytds ukládám 2 údaje: index seznamu + hodnotu, abych
    # při vypisování mohl údaje správně spárovat. A do mytds ukládám jen 'řádky', jejichž
    # hodnoty se ze stránky načetly. Ale netuším, jak zkonstruovat ten .extend (nebo .append),
    # aby mi fungovalo následující mytds[i][1].text
    if data:
        mytds.extend([[i, data]])

for i in range(len(mytds)):
    txt=seznam[i]+": "+mytds[i][1].text
    print(txt)

Nahlásit jako SPAM
IP: 95.140.241.–
gna
~ Anonymní uživatel
1891 příspěvků
26. 9. 2023   #2
-
+2
-
Zajímavé
Kit +

Chceš to vysvětlit, nebo jen rozchodit? :)

from bs4 import BeautifulSoup
import requests

url = 'https://www.in-pocasi.cz/aktualni-pocasi/olomouc/'
response = requests.get(url)
soup = BeautifulSoup(response.content, 'lxml')

seznam = ["Čas měření", "Teplota", "Vítr", "Vlhkost", "Tlak", "Srážky dnes", "Změna teploty (30 min)", "Teplota před 24 hodinami", "Rosný bod"]
data = {}

for title in seznam:
    node = soup.find("td", {"data-title": title})
    text = node.text if node else None
    data[title] = text

print(data["Teplota"])  # přístup ke konkrétní hodnotě
for key, val in data.items():  # nebo průchod všech
    print(f"{key}: {val}")
Nahlásit jako SPAM
IP: 213.211.51.–
otula0
Duch
26. 9. 2023   #3
-
0
-

#2 gna
Ahoj, mockrát děkuji! Pokud bys měl náladu a chuť, budu vděčný i za to vysvětlení. Zkusím to sám projít a komentovat, jestli tomu rozumím správně...

from bs4 import BeautifulSoup
import requests

url = 'https://www.in-pocasi.cz/aktualni-pocasi/olomouc/'
response = requests.get(url)
soup = BeautifulSoup(response.content, 'lxml')

seznam = ["Čas měření", "Teplota", "Vítr", "Vlhkost", "Tlak", "Srážky dnes", "Změna teploty (30 min)", "Teplota před 24 hodinami", "Rosný bod"]
data = {} # tady je použito pole typu dict, takže data
          # nebudou jako dvě hodnoty v chlívečku
          # ale jako údaj přiřazený ke svému názvu

# v následujícím cyklu procházíš seznam přímo, ne pomocí
# indexu. Do proměnné 'node' načteš celý tag jako jsem ho
# načítal do 'mytds', rovnou z něj potom vytáhneš tu hodnotu
# do proměnné 'text' (což jsem dělal asi ne úplně 
# optimálně až při zobrazování) a uložíš to jako 
# položku slovníku 'data'
for title in seznam:
    node = soup.find("td", {"data-title": title})
    text = node.text if node else None
    data[title] = text

print(data["Teplota"])  # přístup ke konkrétní hodnotě

# tady je potom načtení všech položek toho slovníku
# přičemž 'data.items()' dává celé dvojice všech položek
for key, val in data.items():  # nebo průchod všech
    print(f"{key}: {val}")
Nahlásit jako SPAM
IP: 37.48.42.–
gna
~ Anonymní uživatel
1891 příspěvků
26. 9. 2023   #4
-
+1
-
Zajímavé

JJ, pochopil jsi to správně. Já jsem tím vysvětlením myslel jestli chceš rozbor proč ti to nefunguje. K tomu bych jen řekl, že není potřeba vytvářet ten pár index-td, protože ten název už je v tom td.

Takže takhle třeba: 

for td in mytds:
    print(td.attrs["data-title"], td.text)

Jinak ta myšlenka není špatná, ale pak nebudeš procházet seznam, ale to mytds, který odkazuje na seznam:

for i, td in mytds:
    print(seznam[i], td.text)

A pak ještě raději použití soup.find místo find_all a tím i list.append místo extend. (Když to td má být jen jedno, tak ať je to v tom kódu explicitně)

Nahlásit jako SPAM
IP: 213.211.51.–
otula0
Duch
26. 9. 2023   #5
-
0
-

#4 gna
Moc děkuji za pomoc. Už se mi to díky tobě podařilo dnes ráno dotáhnout do funkčního celku. Vyučující nám neřekl vůbec nic, jen to, jak proběhne zkouška, nedal nám ani skripta, přičemž v sylabu je takový rozsah znalostí, že i kdyby to byl jediný vyučovaný předmět, tak by na to rok nestačil... Je to k uzoufání...

Nahlásit jako SPAM
IP: 37.48.42.–
Zjistit počet nových příspěvků

Přidej příspěvek

Toto téma je starší jak čtvrt roku – přidej svůj příspěvek jen tehdy, máš-li k tématu opravdu co říct!

Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku

×Vložení zdrojáku

×Vložení obrázku

Vložit URL obrázku Vybrat obrázek na disku
Vlož URL adresu obrázku:
Klikni a vyber obrázek z počítače:

×Vložení videa

Aktuálně jsou podporována videa ze serverů YouTube, Vimeo a Dailymotion.
×
 
Podporujeme Gravatara.
Zadej URL adresu Avatara (40 x 40 px) nebo emailovou adresu pro použití Gravatara.
Email nikam neukládáme, po získání Gravatara je zahozen.
-
Pravidla pro psaní příspěvků, používej diakritiku. ENTER pro nový odstavec, SHIFT + ENTER pro nový řádek.
Sledovat nové příspěvky (pouze pro přihlášené)
Sleduj vlákno a v případě přidání nového příspěvku o tom budeš vědět mezi prvními.
Reaguješ na příspěvek:

Uživatelé prohlížející si toto vlákno

Uživatelé on-line: 0 registrovaných, 11 hostů

 

Hostujeme u Českého hostingu       ISSN 1801-1586       ⇡ Nahoru Webtea.cz logo © 20032024 Programujte.com
Zasadilo a pěstuje Webtea.cz, šéfredaktor Lukáš Churý