HtmlAgilityPack dlaczego mam null w parsowaniu?

HtmlAgilityPack dlaczego mam null w parsowaniu?
D6
  • Rejestracja:ponad 13 lat
  • Ostatnio:około 6 lat
  • Postów:401
0

Mam taki błąd. Wcześniej działało a teraz takie coś mi wyskakuje. Może jest nałożone jakieś zabezpieczenie? Proszę o podpowiedź

Kopiuj
System.NullReferenceException: „Odwołanie do obiektu nie zostało ustawione na wystąpienie obiektu.”

HtmlAgilityPack.HtmlNode.SelectSingleNode(...) zwrócił null.

kod programu

Kopiuj
            string url = @"http://www.baza-firm.com.pl/?vm=zabrze&pg=2&b_szukaj=szukaj";
            HtmlWeb web = new HtmlWeb();

            var doc1 = web.Load(url);

            MessageBox.Show(doc1.ToString());
                

            var nazwa = doc1.DocumentNode.SelectSingleNode("//div/a/span[@itemprop='name']").InnerText; //tu blad
            var ulica = doc1.DocumentNode.SelectSingleNode("//div[@itemprop='streetAddress']").InnerText;
            var kod_pocztowy = doc1.DocumentNode.SelectSingleNode("//div/span[@itemprop='postalCode']").InnerText;
            var miejscowość = doc1.DocumentNode.SelectSingleNode("//div/span[@itemprop='addressLocality']").InnerText;
            var wojewodztwo = doc1.DocumentNode.SelectSingleNode("//div/span[@itemprop='addressRegion']").InnerText;
            var telefon = doc1.DocumentNode.SelectNodes("//div[@class='divSMV_tel1 clearBoth']");
            List<string> lista_tel = new List<string>();
            foreach (var node in telefon)
            {
                lista_tel.Add(node.InnerText);
            }

            MessageBox.Show("nazwa " + nazwa
                            + "\nkod pocztowy " + kod_pocztowy
                            + "\nulica " + ulica
                            + "\nkod pocztowy " + kod_pocztowy
                            + "\nmiejscowość " + miejscowość
                            + "\nwojewództwo " + wojewodztwo
                            + "\ntelefon " + lista_tel[0].ToString());
HC
  • Rejestracja:ponad 8 lat
  • Ostatnio:około 6 lat
  • Postów:30
0

Masz pokręcone xpath.

D6
  • Rejestracja:ponad 13 lat
  • Ostatnio:około 6 lat
  • Postów:401
0
HomoChemicus napisał(a):

Masz pokręcone xpath.
Co niby mam źle? Wcześniej działało teraz po żadnych zmianach nie działa a strona wygląda tek samo.
Tj. jest część HTML tej strony

Kopiuj
<div id="wizidk_1006" class="mwiz_wyr">
<div class="divSMV_daneNazwabold">
<a class="wizLnk" href="http://www.baza-firm.com.pl/maszyny-i-urządzenia-górnicze/zabrze/dak-firma/pl/1006.html" target="_blank" title="DAK-Firma Zabrze">
<span class="przeppoz" itemprop="name">DAK-Firma</span> 
<span class="normalTxt">»</span></a></div>
<div class="smWizLp">.21</div>
<div class="marginTop10 divSMV_daneResztaBK">
<div class="telAddrBox" onclick="window.open('http://www.baza-firm.com.pl/maszyny-i-urządzenia-górnicze/zabrze/dak-firma/pl/1006.html','',''); return false" onmouseover="this.style.cursor='pointer'" itemscope="" itemprop="address" itemtype="http://schema.org/PostalAddress" style="cursor: pointer;"><div class="divSMV_ulica" itemprop="streetAddress">ul. Hermisza 15</div>
<div class="divSMV_kod">
<span itemprop="postalCode">41-800</span>&nbsp;
<span itemprop="addressLocality">Zabrze
</span></div>
<div class="smWizWoj">woj. 
<span itemprop="addressRegion">śląskie</span>
</div>
<div class="divSMV_tel1 clearBoth">
<div itemprop="telephone">tel. (32) 376 20 85</div>
<div itemprop="telephone">fax (32) 376 20 86</div>
</div><div class="smWizPikto">
<span class="pikto_txt" title="+5">więcej »</span>
</div></div>
<div class="smWizLogo">
<a href="http://www.dak-firma.pl/" title="DAK-Firma - http://www.dak-firma.pl/" target="_blank" rel="nofollow">
<img src="http://www.baza-firm.com.pl/firmy/1/1006/logo/1006_logo.gif?t=1149669268" data-src="http://www.baza-firm.com.pl/firmy/1/1006/logo/1006_logo.gif?t=1149669268" alt="DAK-Firma" class="borderNone lazyloaded" width="61" height="65"></a>
</div></div></div>
HC
  • Rejestracja:ponad 8 lat
  • Ostatnio:około 6 lat
  • Postów:30
0

HtmlAguilityPack ma jakiś problem ze stroną. Zauważ, że nie zostaje zaciągnięty kod html. Tu ktoś miał podobny problem.

D6
  • Rejestracja:ponad 13 lat
  • Ostatnio:około 6 lat
  • Postów:401
0

Jest inny sposób pobrania kodu HTML strony? Chyba, że jakoś można to inaczej zrobić w HtmlAguilityPack. Próbowałem też From Browser ale też nie działa. Ciekawy ten problem :)

HC
  • Rejestracja:ponad 8 lat
  • Ostatnio:około 6 lat
  • Postów:30
0

To powinno zadziałać: Jedna z ostatnich odpowiedzi Daj znać czy ruszyło, bo tego nie testowałem

D6
  • Rejestracja:ponad 13 lat
  • Ostatnio:około 6 lat
  • Postów:401
0

Znalazłem rozwiązanie, które podobno działa. Mam problem jednak z zaimplementowaniem go.

Kopiuj
private void button2_ClickAsync(object sender, EventArgs e)
{
string url = @"http://www.baza-firm.com.pl/?vm=zabrze&pg=2&b_szukaj=szukaj";
var doc1 = new HtmlAgilityPack.HtmlDocument();

using (var client = new HttpClient())
{
    var resp = await client.GetAsync(url);
    MessageBox.Show(resp.StatusCode.ToString());
    var html = await resp.Content.ReadAsStringAsync();
    doc1.LoadHtml(html);
}


MessageBox.Show(doc1.DocumentNode.OuterHtml.ToString());
}

Mam taki błąd na słowie "await".

Operatora „await” można używać tylko wewnątrz metody asynchronicznej. Rozważ możliwość oznaczenia tej metody za pomocą modyfikatora „async” i zmiany zwracanego przez nią typu na „Task”.>

Pierwszy raz coś takiego widzę

HC
  • Rejestracja:ponad 8 lat
  • Ostatnio:około 6 lat
  • Postów:30
0

Dodaj przed "void" "async" i będzie śmigać.
PS Teraz poprawnie parsuje stronę.

edytowany 1x, ostatnio: HomoChemicus
Pixello
Jakby był downvote to bym kliknął.
D6
  • Rejestracja:ponad 13 lat
  • Ostatnio:około 6 lat
  • Postów:401
0

A może mi ktoś wytłumaczyć jak to teraz działa? Bardzo jestem zadowolony z tego, że mi to w końcu ruszyło ale chciałbym się nauczyć pisać podobne programy już sam lub też móc innym wytłumaczyć. Chodzi mi głównie o fragment "using (var client = new HttpClient()){..}"

Kopiuj
       private async void  button2_ClickAsync(object sender, EventArgs e)
        {
            string url = @"http://www.baza-firm.com.pl/?vm=zabrze&pg=2&b_szukaj=szukaj";
            var doc1 = new HtmlAgilityPack.HtmlDocument();

            using (var client = new HttpClient())
            {
                var resp = await client.GetAsync(url);
               // MessageBox.Show(resp.StatusCode.ToString());
                var html = await resp.Content.ReadAsStringAsync();
                doc1.LoadHtml(html);
            }


            var nazwa = doc1.DocumentNode.SelectSingleNode("//span[@class='przeppoz']").InnerText;
            var ulica = doc1.DocumentNode.SelectSingleNode("//div[@itemprop='streetAddress']").InnerText;
            var kod_pocztowy = doc1.DocumentNode.SelectSingleNode("//div/span[@itemprop='postalCode']").InnerText;
            var miejscowość = doc1.DocumentNode.SelectSingleNode("//div/span[@itemprop='addressLocality']").InnerText;
            var wojewodztwo = doc1.DocumentNode.SelectSingleNode("//div/span[@itemprop='addressRegion']").InnerText;
            var telefon = doc1.DocumentNode.SelectNodes("//div[@class='divSMV_tel1 clearBoth']");
            List<string> lista_tel = new List<string>();
            foreach (var node in telefon)
            {
                lista_tel.Add(node.InnerText);
            }

            MessageBox.Show("nazwa " + nazwa
                            + "\nkod pocztowy " + kod_pocztowy
                            + "\nulica " + ulica
                            + "\nkod pocztowy " + kod_pocztowy
                            + "\nmiejscowość " + miejscowość
                            + "\nwojewództwo " + wojewodztwo
                            + "\ntelefon " + lista_tel[0].ToString());
        }
    }
edytowany 2x, ostatnio: dawid653
HC
  • Rejestracja:ponad 8 lat
  • Ostatnio:około 6 lat
  • Postów:30
0

Dzięki using(..){} nie musisz wywoływać client.Dispose(true).

Pixello
  • Rejestracja:prawie 10 lat
  • Ostatnio:4 miesiące
  • Lokalizacja:Podkarpacie
  • Postów:448
0
HomoChemicus napisał(a):

Dodaj przed "void" "async" i będzie śmigać.
PS Teraz poprawnie parsuje stronę.

To najgorsza rada jaką możesz dać. W przypadku exceptiona nie będzie żadnego sensownego response.

W przypadku metod async trzeba używać Task lub wersji Task<T> inaczej to proszenie sie o kłopoty.

Ostatnio widziałem kod gdzie z WebApi były zwracane void i się geniusz dziwił dlaczego 500 nie dostaje... Tu będzie podobnie...

edytowany 1x, ostatnio: Pixello
HC
Widać przecież, że to kod do sprawdzenia jak to działa. Finalnie ja bym wydzielił to do metody, która zwróciłaby mi Task<List> z rezultatami parsowania.
D6
To wytłumacz mi jak to powinno wyglądać poprawnie i dlaczego.
Pixello
  • Rejestracja:prawie 10 lat
  • Ostatnio:4 miesiące
  • Lokalizacja:Podkarpacie
  • Postów:448
0

Tak jak napisał @HomoChemicus warto by to wydzielić, inaczej, prędzej czy później, najdzie Cię ochota żeby użyć tego jeszcze gdzieś, zrobisz await button2_ClickAsync(null, null) i przez przypadek odpalisz "Fire and forget".

D6
  • Rejestracja:ponad 13 lat
  • Ostatnio:około 6 lat
  • Postów:401
0

Wyskakuje mi błąd "Błąd CS0021 Do wyrażenia typu „Task<string[,]>” nie można zastosować indeksowania przy użyciu konstrukcji []." =. Jak to powinno wyglądać teraz kod jeżeli chcę wyświetlić wynik bo tego "Task<>" trochę nie rozumiem.

Kopiuj
   class nowa
    {
        public async Task<String[,]> co()
        {
            string url = @"http://www.baza-firm.com.pl/?vm=zabrze&pg=2&b_szukaj=szukaj";
            var htmlDoc = new HtmlAgilityPack.HtmlDocument();

            using (var client = new HttpClient())
            {
                var resp = await client.GetAsync(url);
                // MessageBox.Show(resp.StatusCode.ToString());
                string html = await resp.Content.ReadAsStringAsync();


                htmlDoc.LoadHtml(html);
            }
            var nazwa = htmlDoc.DocumentNode.SelectNodes("//div/a/span[@itemprop='name']");
            List<string> lista_nazwa = new List<string>();
            foreach (var node in nazwa)
            {
                lista_nazwa.Add(node.InnerText);
            }

            var telefon = htmlDoc.DocumentNode.SelectNodes("//div[@class='divSMV_tel1 clearBoth']");
            List<string> lista_tel = new List<string>();
            foreach (var node in telefon)
            {
                lista_tel.Add(node.InnerText);
            }

            String[,] tablica = new string[35, lista_nazwa.Count];

            for (int i = 0; lista_nazwa.Count > i; i++)
            {
                tablica[0, i] = lista_nazwa[i].ToString();
                tablica[1, i] = lista_tel[i].ToString();
            }

            return tablica;

        }
    }

        private void  button2_ClickAsync(object sender, EventArgs e)
        {
            nowa nw = new nowa();
            Task <String[,]> wynik_parsowania = nw.co();
            //MessageBox.Show(wynik_parsowania[0,0]);
          string a =  wynik_parsowania[0, 0]; //blad

        }
Ktos
Moderator
  • Rejestracja:prawie 23 lata
  • Ostatnio:około 5 godzin
0

Twoja funkcja co() (beznadziejna nazwa, zmień na jakąś sensowną) zwraca Task<string[,]>, czyli tak naprawdę nie zwraca tablicy stringów, tylko taki specjalny obiekt związany z async/await. Wynika to z tego, że funkcja co() jest oznaczona jako async (bo awaituje asynchroniczne metody pochodzące z HttpClient).

W swojej funkcji button2_ClickAsync musisz użyć await:

Kopiuj
nowa nw = new nowa();
var wynik_parsowania = await nw.co();
string a =  wynik_parsowania[0, 0];

I dodać słowo kluczowe async również do funkcji button2_ClickAsync (która pewnie miała być async, bo tak się nazywa, ale z jakichś powodów nie jest).

D6
  • Rejestracja:ponad 13 lat
  • Ostatnio:około 6 lat
  • Postów:401
0

Dzięki :) a możesz mi jeszcze napisać gdzie mogę poczytać wyjaśnienia i sposób działania użytych tutaj metod w kodzie? Jakąś książkę lub artykuł w necie. Chcę to zrozumieć dokładnie żebym już nie musiał pytać i wiedzieć do czego można jeszcze to wykorzystać

HC
  • Rejestracja:ponad 8 lat
  • Ostatnio:około 6 lat
  • Postów:30
0

Masz to ładnie wyłożone w C# 6.0 Kompletny przewodnik dla praktyków. Co do kodu, to zwracałbym obiekt z wynikami parsowania.

Kliknij, aby dodać treść...

Pomoc 1.18.8

Typografia

Edytor obsługuje składnie Markdown, w której pojedynczy akcent *kursywa* oraz _kursywa_ to pochylenie. Z kolei podwójny akcent **pogrubienie** oraz __pogrubienie__ to pogrubienie. Dodanie znaczników ~~strike~~ to przekreślenie.

Możesz dodać formatowanie komendami , , oraz .

Ponieważ dekoracja podkreślenia jest przeznaczona na linki, markdown nie zawiera specjalnej składni dla podkreślenia. Dlatego by dodać podkreślenie, użyj <u>underline</u>.

Komendy formatujące reagują na skróty klawiszowe: Ctrl+B, Ctrl+I, Ctrl+U oraz Ctrl+S.

Linki

By dodać link w edytorze użyj komendy lub użyj składni [title](link). URL umieszczony w linku lub nawet URL umieszczony bezpośrednio w tekście będzie aktywny i klikalny.

Jeżeli chcesz, możesz samodzielnie dodać link: <a href="link">title</a>.

Wewnętrzne odnośniki

Możesz umieścić odnośnik do wewnętrznej podstrony, używając następującej składni: [[Delphi/Kompendium]] lub [[Delphi/Kompendium|kliknij, aby przejść do kompendium]]. Odnośniki mogą prowadzić do Forum 4programmers.net lub np. do Kompendium.

Wspomnienia użytkowników

By wspomnieć użytkownika forum, wpisz w formularzu znak @. Zobaczysz okienko samouzupełniające nazwy użytkowników. Samouzupełnienie dobierze odpowiedni format wspomnienia, zależnie od tego czy w nazwie użytkownika znajduje się spacja.

Znaczniki HTML

Dozwolone jest używanie niektórych znaczników HTML: <a>, <b>, <i>, <kbd>, <del>, <strong>, <dfn>, <pre>, <blockquote>, <hr/>, <sub>, <sup> oraz <img/>.

Skróty klawiszowe

Dodaj kombinację klawiszy komendą notacji klawiszy lub skrótem klawiszowym Alt+K.

Reprezentuj kombinacje klawiszowe używając taga <kbd>. Oddziel od siebie klawisze znakiem plus, np <kbd>Alt+Tab</kbd>.

Indeks górny oraz dolny

Przykład: wpisując H<sub>2</sub>O i m<sup>2</sup> otrzymasz: H2O i m2.

Składnia Tex

By precyzyjnie wyrazić działanie matematyczne, użyj składni Tex.

<tex>arcctg(x) = argtan(\frac{1}{x}) = arcsin(\frac{1}{\sqrt{1+x^2}})</tex>

Kod źródłowy

Krótkie fragmenty kodu

Wszelkie jednolinijkowe instrukcje języka programowania powinny być zawarte pomiędzy obróconymi apostrofami: `kod instrukcji` lub ``console.log(`string`);``.

Kod wielolinijkowy

Dodaj fragment kodu komendą . Fragmenty kodu zajmujące całą lub więcej linijek powinny być umieszczone w wielolinijkowym fragmencie kodu. Znaczniki ``` lub ~~~ umożliwiają kolorowanie różnych języków programowania. Możemy nadać nazwę języka programowania używając auto-uzupełnienia, kod został pokolorowany używając konkretnych ustawień kolorowania składni:

```javascript
document.write('Hello World');
```

Możesz zaznaczyć również już wklejony kod w edytorze, i użyć komendy  by zamienić go w kod. Użyj kombinacji Ctrl+`, by dodać fragment kodu bez oznaczników języka.

Tabelki

Dodaj przykładową tabelkę używając komendy . Przykładowa tabelka składa się z dwóch kolumn, nagłówka i jednego wiersza.

Wygeneruj tabelkę na podstawie szablonu. Oddziel komórki separatorem ; lub |, a następnie zaznacz szablonu.

nazwisko;dziedzina;odkrycie
Pitagoras;mathematics;Pythagorean Theorem
Albert Einstein;physics;General Relativity
Marie Curie, Pierre Curie;chemistry;Radium, Polonium

Użyj komendy by zamienić zaznaczony szablon na tabelkę Markdown.

Lista uporządkowana i nieuporządkowana

Możliwe jest tworzenie listy numerowanych oraz wypunktowanych. Wystarczy, że pierwszym znakiem linii będzie * lub - dla listy nieuporządkowanej oraz 1. dla listy uporządkowanej.

Użyj komendy by dodać listę uporządkowaną.

1. Lista numerowana
2. Lista numerowana

Użyj komendy by dodać listę nieuporządkowaną.

* Lista wypunktowana
* Lista wypunktowana
** Lista wypunktowana (drugi poziom)

Składnia Markdown

Edytor obsługuje składnię Markdown, która składa się ze znaków specjalnych. Dostępne komendy, jak formatowanie , dodanie tabelki lub fragmentu kodu są w pewnym sensie świadome otaczającej jej składni, i postarają się unikać uszkodzenia jej.

Dla przykładu, używając tylko dostępnych komend, nie możemy dodać formatowania pogrubienia do kodu wielolinijkowego, albo dodać listy do tabelki - mogłoby to doprowadzić do uszkodzenia składni.

W pewnych odosobnionych przypadkach brak nowej linii przed elementami markdown również mógłby uszkodzić składnie, dlatego edytor dodaje brakujące nowe linie. Dla przykładu, dodanie formatowania pochylenia zaraz po tabelce, mogłoby zostać błędne zinterpretowane, więc edytor doda oddzielającą nową linię pomiędzy tabelką, a pochyleniem.

Skróty klawiszowe

Skróty formatujące, kiedy w edytorze znajduje się pojedynczy kursor, wstawiają sformatowany tekst przykładowy. Jeśli w edytorze znajduje się zaznaczenie (słowo, linijka, paragraf), wtedy zaznaczenie zostaje sformatowane.

  • Ctrl+B - dodaj pogrubienie lub pogrub zaznaczenie
  • Ctrl+I - dodaj pochylenie lub pochyl zaznaczenie
  • Ctrl+U - dodaj podkreślenie lub podkreśl zaznaczenie
  • Ctrl+S - dodaj przekreślenie lub przekreśl zaznaczenie

Notacja Klawiszy

  • Alt+K - dodaj notację klawiszy

Fragment kodu bez oznacznika

  • Alt+C - dodaj pusty fragment kodu

Skróty operujące na kodzie i linijkach:

  • Alt+L - zaznaczenie całej linii
  • Alt+, Alt+ - przeniesienie linijki w której znajduje się kursor w górę/dół.
  • Tab/⌘+] - dodaj wcięcie (wcięcie w prawo)
  • Shit+Tab/⌘+[ - usunięcie wcięcia (wycięcie w lewo)

Dodawanie postów:

  • Ctrl+Enter - dodaj post
  • ⌘+Enter - dodaj post (MacOS)