Diskuze: Corona program ciselny udaj nakazenych
V předchozím kvízu, Test znalostí C# .NET online, jsme si ověřili nabyté zkušenosti z kurzu.

Člen

Zobrazeno 44 zpráv z 44.
//= Settings::TRACKING_CODE_B ?> //= Settings::TRACKING_CODE ?>
V předchozím kvízu, Test znalostí C# .NET online, jsme si ověřili nabyté zkušenosti z kurzu.
Samozrejme stánku som zabudol pridať https://www.worldometers.info/coronavirus/?…
Tak skúsil som toto do konzoli mi to vypíše niečo z tej stránky ale ten
retazec co najdem cez operu mi do konzoli nevypise
using System;
using System.Net.Http;
using System.Threading.Tasks;
namespace DownloadPageHttpClient
{
class Program
{
static async Task Main(string[] args)
{
using var client = new HttpClient();
client.DefaultRequestHeaders.Add("User-Agent", "C# console program");
var content = await client.GetStringAsync("https://www.worldometers.info/coronavirus/?fbclid=IwAR2hjFNZpDQ5GqxLBv6z5HQXophgSMGvj4VnYZsmUdvZ7mGSxWwMe46caJY#countries");
Console.WriteLine(content);
}
}
}
K načítání dat z jiné stránky potřebuješ API. K tomu se dají použít XML feedy.
Tak som znovu pokročil toto je začiatok toho čo sa mi vypíše do konyoli
<tr style="">
<td style="font-weight: bold; font-size:15px; text-align:left;">Barbados</td>
<td style="font-weight: bold; text-align:right">14</td>
<td style="font-weight: bold; text-align:right;background-color:#FFEEAA;">+8</td>
<td style="font-weight: bold; text-align:right;"> </td>
<td style="font-weight: bold; text-align:right;"></td>
<td style="font-weight: bold; text-align:right"></td>
<td style="text-align:right;font-weight:bold;">14</td>
<td style="font-weight: bold; text-align:right"></td>
<td style="font-weight: bold; text-align:right">49</td>
</tr>
Vidiet tam Barbados a počet nakazených a pokračuje to tak až na koniec tej tabulky ktorá je na webovej stránke.Otázka je že prečo mi tú tabulku nenačíta odzačiatku?
Asi takhle, to, co sem dáváš nemá žádný smysl. To je pouze HTML. Z HTML nikdy žádná dynamická data nedostaneš. Potřebuješ serverový programovací jazyk, třeba PHP nebo C#, který bude komunikovat s databází a z ní vypisovat data do HTML šablony. Pak další část (API) bude v nějakém intervalu získávat data ze zdrojového serveru, případně souboru a ukládat je do tvé databáze. Jde to i napřímo, ale riskuješ, že nebudou data dostupná ani u tebe, když vypadne server zdroje. Podle mně sis ukousl příliš velké sousto. Tohle jsou už pokročilejší techniky a začátečník je nemůže nikdy zvládnout.
Ahoj vďaka za odpoveď. Ja si tiež myslím že je to veľké sústo.Ale k veci myslím že tá stránka https://www.worldometers.info/coronavirus/ si tie dáta berie z nejakej databázy lenže do tej ja prístup nemám. Proste som chcel napísať program čo by prečítal dáta z tej stránky, ked to dokáže prehliadač mal by to aj nejaký jednoduchý program, nejak (to by nemal byť taký problém) by som v tých dátach našiel tie dva údaje čo potrebujem a potom by som s tým už asi vedel pracovať.A áno ako píšeš plánoval som, že tie dáta by sa z tej stránky načítavali v nejakom intervale.To že vypadne server by mi nevadilo nepotrebujem neaktuálne dáta a keď nepôjde tá stránka tak by som zastaralý údaj nepotreboval.
Tomuhle se říká data scraping.
V tech několika případech, kdy jsou tohle řešil se mi osvědčil HtmlAgilityPack. Ten stránku stáhne, zparsuje jí do jekéhosi dokumentu, který obsahuje strom stránky. Nad tímhle dokumentem je následně možno vykonávat XPath dotazy, kterýma si vytáhneš, co potřebuješ.
Schválně jsem si to napsal. Zdroják je tady.
Spustíš to nějak takhle:
var s = new Scraper();
var dataZemi = s.Scrapovat();
Console.WriteLine(CountryData.FormatString, "Zeme", "Total", "Deaths", "Rate [%]");
dataZemi.ForEach(Console.WriteLine);
Vystup pak vypada viz priloha.
Ahoj,
jak již zde bylo řečeno, tento působ není úplně ideální. Jsi takto
závislý na "vizuální podobě" stránky, která se může často měnit a to
může způsobovat chyby. Mnohem lepší řešení je použití nějakého tzv.
API, které ti data vrátí v předem známém a neměnném formátu, který je
dobře strojově čitelný, typicky to bývá json nebo xlm. Ale pokud taková
možnost není, tak je samozřejmě možné i stáhnout a naparsovat kód té
stránky.
Nejjednodušší způsob, jak to udělat je za pomocí HtmlAgilityPack, ale
jsou i jiné způsoby. Jak tedy na to:
Nejprve je nutné vložit do projektu balíček HtmlAgilityPack: V okně
Solution Explorer (vpravo ve Visual Studiu) klikni pravým na tvůj projekt a
vyber "Manage NuGet Packages...". Následně vlevo nahoře vyber "Browse" a do
vyhledávacího políčka napiš "HtmlAgilityPack" a potvrď. Měl by se
zobrazit seznam, kde jako první bude HtmlAgilityPack. Ten vyber a vpravo klikni
na "Install", následně "OK" a vrať se k tvému kódu.
Zde je metoda pro získání počtu nakažených:
public static int getByCountry(string country)
{
HtmlWeb htmlWeb = new HtmlWeb();
HtmlDocument document = htmlWeb.Load("https://www.worldometers.info/coronavirus/");
HtmlNodeCollection rows = document.DocumentNode.SelectNodes("//*[@id=\"main_table_countries_today\"]/tbody[1]/tr");
foreach (HtmlNode row in rows)
{
HtmlNodeCollection columns = row.SelectNodes("td");
if (columns[0].InnerText == country)
{
return int.Parse(Regex.Replace(columns[1].InnerText, "[^.0-9]", ""));
}
}
throw new Exception("Stát nenalezen!");
}
A použití je již triviální, radši ale uvedu:
Console.WriteLine(getByCountry("Slovakia"));
Pokud již znáš a využíváš OOP, tak si metodu uprav a vlož do nějaké třídy.
Kdyby jsi měl jakýkoliv problém, neváhej napsat
Ahojte ďakujem obom za pomoc určite to dalo dosť práce,no bohužiaľ ani
jeden kód mi nefunguje.
Bugmaster tvoj kód vyzerá skvelo sú tam aj veci ktoré nepotrebujem no to by
mi nevadilo jednoducho ich odignorujem Ten výpis čo si poslal vyzerá
úžasne. Avšak keď chcem spustiť tvoj kód vypíše mi chybu CS5001 a vôbec
sa nechce skompilovať. Snažil som sa tam pridávať tento riadok static void
Main(string[] args) lebo tak som to pochopil že tam chýba ten. No po hodine
googlenia a snaženia som to vzdal.
Jan Kerhart Tvoj kód vyzerá o dosť jednoduchšie a vďaka za návod ako
nainštalovať ten NuGet, ja som tam vždy písal Install-Package
HtmlAgilityPack -Version 1.11.23 ,no ten tvoj spôsob je rýchlejší. No
bohužiaľ ani tvoj kód mi nefunguje. Mal som chybu, bolo podčiarknuté slovko
Regex a ponúklo mi to opravu že mám pridať using
System.Text.RegularExpressions;
tak som to spravil. Ten riadok aby mi vypísalo do konzoly ten text
Console.WriteLine(getByCountry("Slovakia"));
som skúšal pridať do hocijakej časti programu no vždy neúspešne. Program
prebehol bez chyby no v konzole sa nič nevypísalo.
Oh ano, funkci Main() urcite potrebujes. To mě nějak nenapadlo zminit
Tady si muzes ten muj repozitar stahnout. Psal jsem to ve Visual Studiu 2019. Melo by to tam jit normalne otevrit a spustit.
Mozna radsi jeste pridej jako posledni radek ve funkci Main() tohle:
Console.ReadKey();
Jinak se totiz muze stat, ze se konzole otevre a po ukonceni hned zase zavre.
Vďaka toto už funguje.Idem sa s tým hrať a upraviť si to podla seba.
Ahoj tak znova píšem, pri tom ako som si prispôsoboval program od Bugmastera som si všimol kde som robil chybu v programe od Jan Kerhart a funguje mi už aj ten. Dalej budem používať už len jeho kód ,lebo je jednoduchší a hneď vypíše len to číslo čo potrebujem. Ale vďaka aj tebe Bugmaster veľa som sa naučil.
Tak mám asi triviálnu otázku ale predsa. Mám v program.cs premennú nakazeny() a chcel by som ju použit vForm1.cs no nedarí sa mi prísť na to ako. Premenné z Form1.cs viem používať v Program.cs ale žiadnu premennú z Program.cs neviem použiť v Form.cs Dúfam že ste to pochopili. Dakujem vopred za rady.
Co znamená
Mám v program.cs premennú nakazeny()
Jakého typu má být ta proměnná? A pokud tam máš ta závorky, tak to
není proměnná, ale nějaká funkce...
Pokud chceš něco z "program.cs" použít ve "Form1", tak ten form musí
vědět o tom program.cs, tzn, že musíš mít ve Form1 instanci toho
program.cs.
Michal Štěpánek ano už som asi pochopil mal som kód.
int nakazeny()
{
foreach (HtmlNode row in rows)
{
HtmlNodeCollection columns = row.SelectNodes("td");
if (columns[0].InnerText == country)
{
return int.Parse(Regex.Replace(columns[1].InnerText, "[^.0-9]", ""));
}
}
throw new Exception("Stát nenalezen!");
}
A do msgboxu som používal nakazeny() a vypísalo my to číslo myslel som
si že tým intom je to zadefinované ako premenná ale asi je to funkcia
však?
Tak som napísal string strnakazeny = nakazeny().ToString();
a to strnakazeny už je premenná že?
"Pokud chceš něco z "program.cs" použít ve "Form1", tak ten form musí
vědět o tom program.cs, tzn, že musíš mít ve Form1 instanci toho
program.cs."
ale na toto som stále neprišiel ako sa robí.
A co vlastně v tom program.cs máš, že to potřebuješ použít ve formu?
To by měla být podle mě statická třída, kterou vytváří VS při
vytvoření projektu a v ní by měly být deklarovány maximálně statické
proměnné. Pokud chceš něco provádět v nějaké třídě mimo form (tak by
to mělo být), měl by sis nějakou třídu vytvořit sám.
Např.:
public class Machine
{
public int Id { get; set; }
public string Nazev {get; set;}
public string Popis { get; set; }
}
a pak ve formu dáš instanci té třídy, např.:
public partial class Form1 : Form
{
Machine m = new Machine();
public Form1()
{
InitializeComponent();
//příklad použití proměnné z té třídy
m.Nazev = "Pepa";
}
}
Program m = new Program(); som skúšal dať do form no vypisovalo mi niečo
take že to nemôžem použit na static class
public int nakazeny() ked som dal pred int alebo string public tak mi tam
povyskakovalo červene more chyb.
Ale poradil som si, vyriešil som to inak. Celý program z program.cs som
presunul do form a z program.cs spúštam iba ten form. A funguje to krásne.
Teraz sa budem hrať s grafikou to nieje také zložite nato je kopa
návodou.
Mojim cielom by bolo aby sa to dalo nainštalovať a vyzeralo by to takto https://i.stack.imgur.com/Uhv9q.png len namiesto rýchlostí
by tam boli počty nakazených.Ale nato som našiel asi 2 vlákna na jednom
fóre, takže to určite nedokážem.
Chyby ti tam vyskákaly, protože je to statická třída, jak jsem psal
před tím.
Z hlediska OOP bys ale funkce měl mít oddělené od formu ve vlastní třídě
(priklad jsem psal taky výše)
Ahojte kolega vyššie mi napísal tento kód
public static int getByCountry(string country)
{
HtmlWeb htmlWeb = new HtmlWeb();
HtmlDocument document = htmlWeb.Load("https://www.worldometers.info/coronavirus/");
HtmlNodeCollection rows = document.DocumentNode.SelectNodes("//*[@id=\"main_table_countries_today\"]/tbody[1]/tr");
foreach (HtmlNode row in rows)
{
HtmlNodeCollection columns = row.SelectNodes("td");
if (columns[0].InnerText == country)
{
return int.Parse(Regex.Replace(columns[1].InnerText, "[^.0-9]", ""));
}
}
throw new Exception("Stát nenalezen!");
}
Ja som si ho upravil na tento
string country = ("Slovakia");
HtmlWeb htmlWeb = new HtmlWeb();
HtmlAgilityPack.HtmlDocument document = htmlWeb.Load("https://www.worldometers.info/coronavirus/");
HtmlNodeCollection rows = document.DocumentNode.SelectNodes("//*[@id=\"main_table_countries_today\"]/tbody[1]/tr");
string nakazeny = "";
{
foreach (HtmlNode row in rows)
{
HtmlNodeCollection columns = row.SelectNodes("td");
if (columns[0].InnerText == country)
{
nakazeny = columns[1].InnerText;
}
}
}
a tiež mi funguje a vyzerá jednoduchšie.Vedeli by ste mi nejak vysvetliť funkciu toho Parse(Regex.Replace a throw new Exception("Stát nenalezen!"); totiž robilo mi to problémy ked tá zdrojová tabulka na servery neobsahovala číslo.Teraz s mojim kódom mi to funguje.
Throw new Exception je vyvolání výjímky, když neexistuje nějaký údaj. Když proceduru nebo funkci spustíš v try-catch bloku, můžeš v něm ošetřit, jak se má program chovat při té výjímce
try
{
//nějaká funkce
}
//tady se nastaví co se má stát, když se vyvolá výjímka
catch (Exception ex)
{
MessageBox.Show("Export dat se nezdařil - " + ex.Message, "Chyba", MessageBoxButton.OK, MessageBoxImage.Exclamation);
}
//tento kus (finnaly) se použít nemusí, ale může, když chceš, aby se něco provedlo i při vyvolání výjímky
finally
{
//toto se provede v každém případě
}
P.S. Všechno je to popsáno tady na itnetwork v tutoriálech. Neměl bys přeskakovat v učení začátky, jinak se v tom budeš jen plácat a budeš páchat slepeniny místo správně psaných programů.
Ahoj neviem kde robím chybu snažím sa rozložiť si program do
jednotlivých súborov no nechce mi to na seba nadviazať.
Mám súbor Scrapper.cs a v ňom tento kód
using HtmlAgilityPack;
namespace Corona
{
public class Scrapper
{
public void scrappovat()
{
string country = ("Slovakia");
HtmlWeb htmlWeb = new HtmlWeb();
HtmlAgilityPack.HtmlDocument document = htmlWeb.Load("https://www.worldometers.info/coronavirus/");
HtmlNodeCollection rows = document.DocumentNode.SelectNodes("//*[@id=\"main_table_countries_today\"]/tbody[1]/tr");
{
foreach (HtmlNode row in rows)
{
HtmlNodeCollection columns = row.SelectNodes("td");
if (columns[0].InnerText == country)
{
string nakazeny = columns[1].InnerText;
string mrtvy = columns[3].InnerText;
string vylieceny = columns[5].InnerText;
}
}
}
}
}
}
Potom mám súbor Form1.cs a vnom tento kód
using System.Windows.Forms;
using System.Media;
namespace Corona
{
public partial class Form1 : Form
{
Scrapper scrapper = new Scrapper();
public Form1()
{
scrapper.scrappovat();
InitializeComponent();
label1.Text = scrapper.nakazeny;
label2.Text = scrapper.mrtvy;
label3.Text = scrapper.vylieceny;
Neviem kde robím chybu ale ten súbor form1.cs nevidí premenné zo súboru Scrapper.cs pričom tam mám public class a aj tento riadok Scrapper scrapper = new Scrapper(); ktorý by ma mal odkázať na celý ten súbor nie?
Scrapovat() ti vytvoří vypis (list) hodnot a to se nedá zobrazit v jednom labelu, musíš na to použít datagrid, nebo listview
Tak som znova pokročil, prišiel som nato ako si odkazovať na jednotlivé
subory voidy a classy. Myslím že už mi to celkom ide.Vytvoril som si tam aj
form nastavenia kde si viete nastavovať veci. Chcel by som aby sa tie
nastavenia niekam ukladali aj po ukončení programu a znova sa načítali keď
sa program spustí.
Našiel som však kopu rôznych spôsobov ako to spraviť. Ktorý by ste mi
odporučili vy?
Použil som tento navod a funguje mi to dobre https://docs.microsoft.com/…-with-csharp
Pokud ti to vyhovuje, je to OK. Jinak bys mohl pro "nastavení" použít ukládání např. do *.ini nebo *.xml souborů a při spuštění aplikace to z toho souboru zase načíst...
Ahojte zasa si neviem rady. Potreboval by som aby mi program vypísal do comboboxu zoznam krajín.Skúšam to zatial s konzolou. Mám túto časť kódu
foreach (HtmlNode row in rows)
{
HtmlNodeCollection columns = row.SelectNodes("td");
countryname = columns[0].InnerText;
Console.WriteLine(countryname);
Funguje dobre ale ked vo forme napíšem
public Form1()
{
Console.WriteLine(scrapper.countryname);
Tak sa vypíše len jedna krajna.
Potreboval by som to nejak vyriešiť.
Ty krajiny musíš vypsat do nějaké kolekce a tu kolekci pak vzít jako
zdroj dat pro combobox, nebo při procházení krajin je musíš plnit do toho
comboboxu.
Evidentně jsi přeskočil několik lekcí při učení. Vrať se k učení,
prostuduj si místní tutoriály a pak teprve páchej takový program.
Většina toho, na co se tu ptáš jsou základy programování a je to všechno
tady v tutoriálech popsáno...
No našiel som si tie kolekcie. Funguje mi to v tom súbore scrapper. Ale ked
to chcem aby mi to išlo aj v tom Forme tak neviem ako to napísať lebo ten
var countryname = new List<string>();
neviem dať ako public
Nepoužívej zbytečně "var", kde nemusíš. To se používá ve chvíli,
kdy nevíš, jakého typu bude ta proměnná nebo kolekce
ve třídě deklaruješ list
Public List<string> countryname;
a pak ho aplikuješ
countryname = new List<string>();
Dakujem toto som aj písal public List<string> countryname; a skúšal ale toto som už nevedel že treba countryname = new List<string>(); vdaka už to ide.
Ahoj no popravde ma napadlo aj to že by som spravil aplikáciu na android a dal to na play. Ale napadlo ma že tá stránka z ktorej čerpám dáta nieje moja a určite by sa im to nepáčilo keby sa to dozvedeli. Takto to mám len pre seba, ukázal som to pár kamarátom a keď s tým budem spokojný dám to sem do vlákna nech sa podelím.Hlavne s ludmi čo mi pomáhali.
Ahoj mám problém. Program sa mi občas nie vždy ukončí a vypíše mi
tento dôvod
The program '[12700] Corona.exe' has exited with code -1073741819 (0xc0000005)
'Access violation'.
Hľadal som na nete, ale je tam toho strašne veľa a nevyznám sa v tom, ale ak
som dobre pochopil tak je to niečo s pamätou.
V kóde chybu nevidím a prišiel som nato kedy mi to robí. Ked prehrávam jednu pesničku ktorá má cca 4MB a dávam často načítavať dáta z tej stránky. Ked púšťam inú pesničku ktorá ma cca 1MB tak to nerobí. Ale predsa by nemal byť problém aby mala pesnička hocakú veľkosť, nie?
Podle mě se písnička načte do paměti, aby se mohla přehrávat, čím "větší" písnička, tím více paměti a při opakovaném načítání dat z toho tvého programu dojde k přetečení paměti...
Ahoj pesničky sa mi ukladajú/kódujú do .exe súboru.Pomohlo by ak by som ich ukladal do priečinka s exe súborom a načítaval odtiaľ? Hľadal som niečo o tej pamäti či sa nedá zväčšiť no nič som nenašiel. Dočítal som sa že tú pamäť prideľuje windows a nedá sa zväčšiť. Príde mi to nejaké divné že prečo mu nepridelí viac tej pamäte keď ju ten program potrebuje.
Ahoj tak som to skúsil. Vo VS som v resources u tých 2 pesničiek dal copy always a oni sa mi teraz automaticky nakopírujú do zložky s programov. Odtiaľ ich načítavam v programe a funguje to pamäť mi už nepreteká. Ale mám taký malý problém. Ako odstránim tú pesničku aby sa nekódovala do programu exe. Totiž ak to mám takto má program 7MB ak z resource odstránim obe pesničky má program 1MB, ale to ich už musím manuálne zakaždým pridávať to tej výslednej zložky s programom. Dá sa tam nejak nastaviť aby boli tie pesničky evidované vo VS a tam mám to copy always aby sa kopírovali do tej zložky, ale už sa nekódovali do exe súboru aby mal 1MB. Dúfam že chápeš je to trochu krkolomne napísané.
Dovolím si nevyžádanou recenzi. Aplikaci jsem neinstaloval, jen narychlo prozkoumal kód.
To jen tak, kdyby ses nudil a chtěl udělat final-final .
Kludne kritika je vítaná. Ako som už viac krát písal niesom programátor
a ani nechcem byť, len som si chcel spraviť takúto aplikáciu, tak som tak
povediac nakukol do tejto oblasti. Rozpíšem sa k tvojim bodom (k niektorým
možno drzo ).
1.Akých výnimiek?
2.Koho?
3.No refresh by som vedel spraviť, ale v pláne nebol. Otvorím aplikáciu
kuknem si stav, hlavne na Slovensku a zavriem ju. Takže refresh som
nepotreboval.
4.Hej to ma napadlo tak 2 verzie dozadu že by som to stiahol a potom triedil,
ale už sa mi s tým nechcelo robiť, hlavne som nevedel ako na to, a až tak mi
to nevadí. Ale hej o tejto chybe/nedostatku viem.
5.Netuším
6.Hej aj o tejto chybe viem, len sa mi nepodarilo zistiť ako, tie pesničky
nezakomponovať do exe tak je to takto. Je to o 6MB väčšie než by mohlo, ale
má to dokopy len 14MB takže som sa s tým uspokojil.
Zobrazeno 44 zpráv z 44.