Dopieścić parseDOM()
Opened this issue · 29 comments
Funkcja parseDOM()
jest namiastką parsera HTML. Jest to alternatywa dla:
- BeautySoap4, który jest koszmarnie wolny;
- lxml najszybszy, który ma też najbardziej zaawansowane wyszukiwanie po xpath, niestety jest binarny, co może powodować problemy w dystrybucji¹.
parseDOM()
jest o tyle istotna, że na niej opera się parsowanie niemal każdej strony.
Funkcję znalazłem w MrKnow. W Cherry (w PWT) jest funkcja zdecydowanie nowsza, lepiej znajdująca elementy, niemniej znacząco wolniejsza.
Zacząłem przerabiać ją aby dało się obłożyć czymś w rodzaju selektora CSS. Mój kod opera się na MrKnow bo parę dni temu jeszcze nie wiedziałem, że jest inna implementacja w PWT. Obecnie łączę cechu obu realizacji, czyli moja wersja niemal tak wolna ja ta z PWT i niemal tak dziurawa jak ta z MrKnow :-D
Głęboki refactoring prowadzę równolegle do innych prac.
API ma być niezmienne z dokładnością do poprawek błędów i dodatkowych funkcji.
¹) Jest nadzieja dla binarnych paczek choć ciągle jest to za dużo zachodu:
Testy wydajnościowe na obecną chwilę dla dość wrednego (1200 dużo krótkich tagów) pliku 800kB.
Czas w sekundach.
Python2
Test | mrknow | cherry | rysson |
---|---|---|---|
tags | 2.207 | 5.138 | 4.949 |
attrs | 1.638 | 1.755 | 1.603 |
Python3
Test | mrknow | cherry | rysson |
---|---|---|---|
tags | 0.381 | 1.029 | 0.837 |
attrs | 0.288 | 0.386 | 0.290 |
Aż szkoda, że Kodi nie obsługuje Pythona 3 :-)
Przykładowe błędy.
Poprawny wynik jest pogrubiony
parseDOM(...) | mrknow | cherry | rysson |
---|---|---|---|
('<a>A</a><a x="1">B</a> ', 'a') |
['A '] |
['A ', 'B '] |
['A ', 'B '] |
('<a z=">">A</a> ', 'a') |
['">A '] |
['">A '] |
['A '] |
('<a>A<a>B</a></a> ', 'a') |
['A<a>B</a> ', ''] |
['A<a>B</a> ', 'B '] |
['A<a>B</a> ', ''] |
od Kodi 18 jest python 3 z tego co się orientuję
Ale i tak nie przepiszemy całości. Choć nowe rzeczy można pisać dualnie, w sensie działające pod Py2 i Py3 na raz. Wtedy łatwiej będzie się przesiadać powoli.
Ale to pieśń przyszłości. Dla Py3 też są różnice w implementacji parseDOM
, tylko każda szybciej się wykonuje to mniej boli.
jednak Python3 będzie full supported w Kodi 19
Jak czytam w migracji w Kodi 18 będą dopuszczane tylko wtyczki z obsługą obu, Py2 i Py3, a od Kodi 19 tylko ze wsparciem Py3.
Czyli jęsli się nie mylę, to w Kodi 18 mamy Py2 (testowo Py3), ale wtyczki mają już być gotowe dla obu.
A w Kodi 19 mamy głównie Py3 (wtyczki mogą olać Py2).
Czyli niedługo i tak nas czeka przepisywanie wszystkiego. Ech...
Reasumując PTW (którego częścią i tak jest ParseDOM) powinno być już kompatybilne z Py2/Py3.
Tak, masz racje. W ogóle strasznie profesjonalnie podchodzisz do tego repozytorium :P Nie mówię, że to źle ale pamiętaj, że masz do czynienia z amatorami (szczególnie jeśli chodzi o mnie), którzy coś tam sobie tylko grzebią w kodzie dla fanu haha :P
I dobrze, bo to jest radocha. Chcę wykorzystać zapał jaki złapałem, oby mi sił starczyło.
Z doświadczenia wiem, że jak się uda coś uporządkować, to potem jest łatwiej rozwijać. Także, a może przede wszystkim, amatorom.
Od brudnej roboty mogę być ja :-)
Część prac, takich typowo technicznych będę prowadził na boku, stąd powyższy link. Nie przejmujcie się tym. Po prostu nie chcę tutaj nawalać pośrednimi etapami (w tym testami).
Tu wrzucę znaczący postęp.
masz do czynienia z amatorami (szczególnie jeśli chodzi o mnie)
Jeśli pozwolicie to ja się w ogóle nie będę wypowiadał w tego typu tematach bo jak dla mnie to czarna magia. Skoro xulek jest amatorem... to ja nawet nie wiem kim jestem. Zajmę się tym co najlepiej mi wychodzi - poprawkami językowymi, układem menu/funkcji grafiką... podsyłaniem pomysłów dot. funkcjonalności... i ogólną obsługą klienta ;) może wyjdzie faktycznie wyjdzie z tego grupa polskich czarodziejów....
Ha ha! Nie krygujcie się. Ktoś musi rządzić, a to ciężka robota :-)
Pomysł grupy, która by długofalowo trzymała pieczę nad projektem jak najbardziej mi się podoba.
Tymczasem migawka wieści z poligonu. Przerabiana funkcja parseDOM()
nie dość, że obsługuje tagi bardziej poprawnie od obu poprzedniczek (od 10 min) to jeszcze jeszcze jest 8 razy szybsza od MrKnow i 19,5 raza szybsza do Cherry.
Sprawdzę wkrótce czy nie ma jakiś błędów ukrytych. Ech, czas się wziąć za unit-testy.
Chyba nie zrozumiałeś - nikt nie kryguje - w końcu cieszymy się że pojawił się specjalista.... 19,5 razy szybciej... to daje dużo możliwości...
Chociaż z drugiej strony... zawodowcy zbudowali Titanica, amatorzy - Arkę Noego. Sądzę że taki team - "zawodowcy", zapaleńcy, amatorzy daje szansę projektowi żeby był zarówno poprawny technicznie jak i przyjazny dla zwykłego usera...
Luz, żartowałem sobie.
Jasne, że to ma największe szanse. Bez technicznych ciężko coś rozwinąć. Ale sami techniczni najczęściej idą w las. Robią sobie coś a nie wiedzą gdzie zmierzają.
Wredny HTML ma 2700 tagów (1200 znajdował błędnie mrknow). Ale mimo wszystko też się mam nadzieję, że to usprawni się parsowanie wszystkich stron. Mniej będziemy czekać na przechodzenie między folderami na Kodi (z reguły wtedy ściąga i parsuje strony).
Nie bardzo czas pozwolił na Kodi-owanie, ale delikatnie dopieszczam tę funkcję.
Parę dni temu zauważyłem, że w Cherry jest ona owijką na inną – parse_dom()
, ale dopiero dzisiaj zauważyłem, że ta nowa ma inny format nieco. Większość funkcjonalności już mam w nowej parseDOM()
. Brakuje mi usuwania komentarzy i zawężenia atrybutów. To ostatnie wygląda na zbędne, choć to zweryfikuję jeszcze. Jest nieco wolniejsza z tym API (~50%, czyli jest 12x szybsza zamiast 19x). Stare API dalej działa z pełną prędkością.
Na stan obecnym do swojej funkcji mam 40 unittestów (299 warunków do sprawdzenia). Wiele już błędów znalazłem. Jak się Wam nudzi to możecie dopisywać swoje. Nawet tutaj.
W weekend powinienem wreszcie rozdzielić PTW i FanFilm (w sensie podzielić bibliotekę).
Możesz dodać obsługę zawartosci html o typie string w funkcji parseDom? Już sprawdzałem sobie i całkiem fajnie to działa
Dzięki. W sumie ona łyka string. Choć miała jeden błąd. Powinno być lepiej.
Dodałem odrobinę dokumentacji dotyczącej parsowania, w którym grzebię:
https://github.com/rysson/kodi-misc/tree/master/ParseDOM/rysson.
@notoco mógłbyś zerknąć czy to da się czytać? Może bym Cię poprosił o poprawki. A może wolicie, aby to pisać po polsku. Albo najlepiej w obu językach (w dwóch plikach).
@xulek, jak możesz to zerknij i zobacz czy API wygląda znośnie pod względem wygody używania.
Jutro postaram się dodać więcej przykładów, takich bardziej z życia.
Jasne, spojrzę jak tylko będę miał dłuższą chwilkę i dam znać. Na pierwszy rzut oka będę musiał chyba do tego przysiąść żeby ogarnąć jak to działa :P Z większą ilością przykładów byłoby super
Jak xulek musi przysiąść, to ja chyba muszę się położyć... Ogólnie coś tam kojarzę i łapię - ale najlepsze by były przykłady z życia wzięte...
Jasne, dorzucę przykłady. Jeszcze moment, bo kolejną rewolucję robię w dom.select(). Chyba dotarłem do granic mojego pojmowania wyrażeń regularnych. Czasem mają ponad 4 linie (a terminal mam 140 znaków szerokości). Niestety regex nie nadaje się do składni rekurencyjnej.
Przerobię parser selektorów i ruszam z przykładami.
P.S. To może ja zrobię dokumentację po polsku (to będzie cenne i tak) a potem kogoś poproszę o przełożenie na angielski. Niestety nie posługuję się nim płynnie i czasem mnie zacina.
Rozpierduchę w parsowaniu zrobiłem, no jeszcze brakuje trochę pracy. Ale już niedługo wyląduje to w PTW.
Jak ktoś się nudzi to proszę potestować z jego mojego roboczego repo.
Na razie tylko python3 (zostały pierdoły, ale czas się skończył 1,5h temu).
Potrzeba jednej biblioteki:
pip3 install Arpeggio
albo
python3 pip install Arpeggio
Potem przejść do repo, do katalogu ParseDOM
i tam zawołać:
python3 -m rysson.dom http://wizja.tv 'center a[href*=watch](href) img(src)'
Można się pobawić. Np. zobaczyć co będzie jak się usunie [href*=watch]
(na początku listy).
Przykłady jutro / (po)²jutrze.
Spoko, nie spiesz się, nikt nas nie goni :P
No wiem, wszyscy mi to mówią. Sam się nakręcam. Zaraz urlop i ciężko będzie na plaży się tym zająć. no chyba, że nas sinice wygonią ;-P
BTW. Jest wersja polska: https://github.com/rysson/kodi-misc/blob/master/ParseDOM/rysson/doc/pl/dom.md
Dalej będę rozwijał wersję polską, oby o życiowe przykłady.
Jak nad Bałtykiem sinice, to na rowery i zwiedzać, zwiedzać zwiedzać. Przerobione nie raz. Z dala od głównych dróg wszędzie pełno ciekawostek.
Myślę, że na razie mi starczy dopieszczania. Co będzie brakowało to dodam.
Oczywiście leży dokumentacja i unittesty.
Po dodaniu mnóstwa bajerów funkcja mi tak zwolniła, że była już tylko ze 40% szybsza od starej z MrKnow. Przysiadłem nad wydajnością. Znów jestem szybszy, 11x od MrKnow i 25x od Cherry. Oczywiście na spreparowanym pliku.
Po poprawkach (czas w sekundach). Ciekawe jest zrównanie się czasów Pythona 2 i 3.
Python2
Test | mrknow | cherry | rysson | rysson.Node |
---|---|---|---|---|
tags | 2.209 | 5.165 | 0.202 | 0.071 |
attrs | 1.626 | 1.759 | 0.085 | — |
Python3
Test | mrknow | cherry | rysson | rysson.Node |
---|---|---|---|---|
tags | 0.393 | 1.121 | 0.202 | 0.072 |
attrs | 0.299 | 0.393 | 0.085 | — |
rysson.Node to pobieranie samych węzłów Node(), w których zarówno atrybuty jak i zawartość jest parsowana na żądanie. Pomiar pokazuje czas samego szukania, bez parsowania.
Stąd ten czas jeszcze krótszy niż dla attrs (który notabene korzysta wewnętrznie z Node).
Więcej dokumentacji tutaj.
@rysson Dobra już mniej więcej sobie ogarnąłem jak to działa tylko mam pytanko, jak tego użyć w Kodi skoro trzeba doinstalować moduł Arpeggio?
To fajnie. Przykład użycia jest w poligon1 w WizjaTV. Trochę to zaawiłe, w planach mam µ-podręcznik na bazie tej wtyczki.
Testowo na własnej maszynie można doinstalować pip2 install Arpeggio
.
Docelowo mamy dwie opcje (co najmniej):
- dołączyć te źródła PTW (jestem przeciw)
- dostarczać osobny script.module.arpeggio (za!)
Jestem za drugim rozwiązaniem, bo dzięki temu nie wiążemy naszych zmian z biblioteką. Ponadto inni mogą sobie z niej skorzystać bez łączenia się z PTW. Mam już do tego skrypty budujące, taki zakręcony bash – chcę przejść na Pythona. Zrobiłem je jeszcze zanim Was znalazłem na potrzeby ożywiania MrKnow. Pobiera z GitHuba i buduje addon dla Kodi. Nawet uwzględnia tagi do znajdywania wersji. Możesz to zobaczyć w repo. Uprzedzam, to nie jest skończone tak jak to chcę ale spokojnie wystarczy, żeby łatwo zbudować Arpeggio (zerknij na plik repos).
Docelowo, jeśli Wam to będzie pasować, chciałbym wyjąć narzędzie do budowy dodatków i całego repo do osobnego git-a. Dzięki temu będziemy mogli zasysać różne źródła (nie tylko cherry-dev) i wszytko wystawiać w jednym repo (cherry). W tym biblioteki całkowicie zewnętrzne.
Za dużo pomysłów, za mało czasu...
Nawet opowiedzieć mam problemy. Może lepiej byłoby usiąść przy piwku i pogadać, ale pewnie tym razem nie będę miał szczęścia, że wszyscy jesteście moimi sąsiadami :-)
Moduł wyjęty do osobnego repo: https://github.com/rysson/pdom