Web scraping dynamicznych stron - pomysły?

0

Szukam ostatnio telewizora do kupna - zauważyłem, że ceny mocno się zmieniają w ciągu doby. Często w nocy wchodzą naprawdę niezłe ceny ( czasem błąd cenowy). Wpadłem pomysł na aplikację. Chciałem napisać takiego scrapera, który byłby procesem w tle i odpytywałby powiedzmy co 10 min strony z konkretnymi modelami telewizorów. Sprawdzałby czy cena jest jakaś promocyjna i wysyłałby mejla do mnie gdyby była jakaś prawdziwa okazja.

No i natrafiłem na pierwszy problem. Strony wszystkich marketów są dynamiczne i cena pojawiają się po chwili z wykorzystaniem skryptów ( pewnie jakiś tam strzał do api jest w celu ustalenia aktualnej ceny). Chciałem skorzystać z HTML Agility Pack ale on radzi sobie świetnie tylko ze statycznymi stronami. Pytanie moje jest - jak sobie z tym poradzić? Czy możliwe jest w ogóle napisanie takiego programu (konsolowa apka, albo proces) w której taki web scraping dynamicznych stron będzie możliwy?

Pogrzebałem chwilę w necie i alternatywą jest Selenium no ale jednak chciałem, żeby finalnie działo się to w tle bez otwierania fizycznego przeglądarki. Macie jakieś pomysły?

5

Użyj np. selenium headless, albo cypress cypress run --headless

2

Faktycznie, HtmlAgilityPack się nie sprawdzi, chyba że będziesz w stanie za każdym razem znaleźć odpowiedni XPath.

Alternatywą dla Selenium w .NET jest świetny wrapper dla Chrome, Cefsharp. Jest też opcja przeglądania browserless, dla aplikacji konsolowych. Choć tutaj się przyda znajomość przynajmniej podstaw JS, bo korzystając zeń wykonujesz skrypty na dokumencie.

Ogólnie polecam.

2

Jeżeli strona używa api do pobierania informacji o cenie telewizora, to najpiewniej używa/wystawia też api do wylistowania telewizorów. Pewnie będziesz musiał trochę poanalizowac query jakie lecą do serwera, filtry itd. ale zdecydowanie jest to moim zdaniem lepsze rozwiązanie. HtmlAgilityPack jest zbędny do takich zastosowań, często wystarczy prosty regex żeby wyciągnąć to co chcesz.

0

Nie znam Cefsharp, ale pobieżnie patrząc wydaje się, że jest to po prostu osadzona przeglądarka. W WinForms jest dostepna kontrolka będąca osadzoną przeglądarką Internet Explorer, nie wiem, czy Cefsharp jest tym samym. W osadzonym IE się bawiłem, jest to proste i tu bardziej dochodzi Javascript. Podobnie, można też osadzić Firefox z wykorzystaniem darmowej kontrolki GeckoFX dostępnej w Internecie.

W obu kontrolkach, do wyświetlonej strony można dopisać dowolną treść (między innymi skrypt JavaScript), a także wywołać dowolną funkcję JavaScript z dowolnymi parametrami.

Co do GeckoFX to nie wiem, ale w przypadku IE, jak wątek GUI jest zawieszony (wykonuje jakiś kod), to przeglądarka jest zablokowana, natomiast nie da się jej uruchomić w wątku innym niż GUI. Z tego powodu, funkcje powinny być uruchamiane ręcznie, lub z wykorzystaniem kontrolki Timer. Jak funkcja JavaScript ma coś zwrócić, to nie należy czekać w pętli na nią (nigdy się nie wykona, bo przeglądarka będzie zablokowana), tylko należy dopisać np. znacznik HTML span lub div z tekstem, a funkcja powinna zmienić tekst w tym znaczniku, a timer w aplikacji C# powinien co jakiś czas odczytywać ten tekst i wyczuć jego zmianę, która daje informację, że funkcja JS się wykonała, a ten tekst można wykorzystać (lub wykorzystać sam fakt wykonania tej funkcji).

1 użytkowników online, w tym zalogowanych: 0, gości: 1