Giter VIP home page Giter VIP logo

kodi-misc's People

Contributors

rysson avatar

Watchers

 avatar  avatar  avatar

kodi-misc's Issues

Interpretacja selektorów

Mam problem.

Wzywam na pomoc @xulek, @notoco , @mbebe, @grzebzi, @po50on. I pozostałych, nie krępujcie się zapraszać choć trochę technicznych ludzi.

Wiem, rozpisałem się, ale proszę o zapoznanie się i komentarz. Łudzę się, że to dla dobra społeczności :-P

Niektórzy z Was pamiętają funkcję parseDOM. W tym roboczym repo jest jej udoskonalona wersja dom.search. I jeszcze ciekawsza dom.select.

Pytanie jest o interpretację rozszerzonej funkcjonalności. Zapraszam do zapoznania się z ułomną dokumentacją. Sam próbuję dojść o co mi chodziło w lipcu :-)

Skrót rozszerzeń

Nieco poważniej, wprowadziłem coś co nazwałem „alternatywą” a właśnie przerobiłem w kodzie na „zestaw” (ang. „set”). Przyświecała mi idea ułatwienia parsowania tabelek i zestawów, np.:

<div class="film">
  <h4>Super tytuł</h4>
  <a href="link1..."><img src="..."/></a>
  <p>Opis.</p>
</div>
<div class="film">
  <h4>Tytuł do bani</h4>
  <a href="link2..."><img src="..."/></a>
  <p>Nie ma co pisać.</p>
</div>
<div class="film">
  <a href="link3...">Reklama</a>
  <p>Nie ma co pisać.</p>
</div>

Można to parsować za pomocą:

for title, link, descr in dom.select(page, 'div.film {h4, a, p}'):
    print('title={title.text!r}, link={link.href}, descr={descr.content!r}', **locals())

I dostaniemy:

'Super tytuł' link1... 'Opis.'
'Tytuł do bani' link2... 'Nie ma co pisać.'

Reklama zostanie pominięta bo nie ma <h4> wymaganego w zestawie.

Do tego dochodzą opcje, czyli można podać np. div.film {h4, a, p?}, jeśli opis w <p> może nie istnieć. Wtedy zamiast Node dostaniemy None. Jest to opisane w dokumentacji.

Pytanie

Selektor zestawu (dawniej alternatywy) można przecież przeplatać.
Jak ma być interpretowany zestaw?

Przypadek zwykły

Opisany wyżej (typu div.film {h4, a, p}), tu wydaje się, że interpretacja jest rozsądna.

Płaska struktura

Wyciąganie {a,b} może dać ciekawe efekty.

HTML Wynik
<a>A1</a> <b>B1> <a>A2</a> <b>B2</b> [ (A1, B1), (A2, B2) ]
<a>A1</a> <a>A2</a> <b>B1> <b>B2</b> [ (A1, B1), (A2, B2) ]
<a>A1</a> <a>A2</a> <a>A3</a> <b>B1> <b>B2</b> [ (A1, B1), (A2, B2) ]

Pierwszy wynik wydaje się OK.
Drugi nieco zadziwia, ale szukamy zestawów A,B, to mamy zestawy.
Trzeci może zaskoczyć, nie ma A3. Po prostu nie ma z czym stworzyć zestawu.

Czy taka interpretacja jest do przyjęcia? Jest to obecna implementacja i wynika z założeń opisanych w pierwszym przypadku (skrót rozszerzeń).

Zestaw z elementami

W zestawie może być użyty selektor, czyli możemy żądać np. {a c, b c}.
Wyszukuje zestawu A, B (zawierających C) i z nich wybiera elementy C.
I tu zaczyna się robić wesoło.

HTML Wynik
<a><c>C1</c></a> <b><c>C2</c></b> <c>Cx</c> [ (C1, C2) ]
<a><c>C1</c></a> <b><c>C2</c><c>C3</c></b> <c>Cx</c> [ (C1, C2) ]
<b><c>C2</c><c>C3</c></b> <c>Cx</c> [ ]
  1. Znalazł A z C1 i B z C2, pobrał oba C, Cx ominął bo nie był ani pod A ani pod B. OK IMHO.
  2. Interesujące, jak wyżej, ale z B pobrał tylko pierwszy element (C2) ignorując C3.
  3. Tu oczywiste, nie ma A, więc zestaw nie istnieje.

W p. 2 mam duże wątpliwości. Czy powinien zwracać C2 czy C2 i C3?
Teraz zwraca zestaw, a on opisuje po jednym elemencie.

Jeśli miałoby zwracać wszystkie, to trzeba zmienić upakowanie (dodatkowe zagłębienie), wtedy
w 1) musi być [ ( [C1], [C2] ) ],
a w 2) [ ( [C1], [C2, C3] ) ].
Przestaje to być czytelne i utrudnia korzystanie z pętli for w stylu podanym na początku.

Nie wiadomo co jest intencją użytkownika tej biblioteki. Może oba warianty mają rację bytu i trzeba dodać jakiś znacznik mówiący czy chcemy wszystkie?
Coś na wzór {a c, b c*} (czyli jeden C z A i wszystkie C z B).

Zestaw i dalszy selektor

Zestaw też jest częścią innego selektora. Nie tylko przed (jak z div.film) ale i za nim mogą być kolejne selektory, np. {a, b} c.

Po małej dzisiejszej przeróbce (bo wylatywał wyjątek) elementy C są wyszukiwane po wybraniu zestawu, czyli wyszukuje wszystkie C z wybranego zestawu.

HTML Wynik
<a><c>C1</c></a> <b><c>C2</c></b> <c>Cx</c> [ [C1], [C2] ]
<a><c>C1</c></a> <b><c>C2</c><c>C3</c></b> <c>Cx</c> [ [C1], [C2, C3] ]

Wydaje się, że taka interpretacja może być.

Apropos poprzedniego punktu. O ile {a, b} c jest wariantem {a c, b c} z wszystkimi C, to generalnie nie jest to zamiennik. Nie da się zamienić {a c, b d}.

Podsumowanie

Bardo proszę o opinie i uwagi. Także o podanie przypadków, które są najbardziej przez Was pożądane. Coś, co by Wam ułatwiło życie. Także z zestawu standardowych selektorów, których obsługuję na razie znikomy podzbiór.

Ze swojego podwórka natknąłem się na problem tych samych znaczników z zestawie. Po prostu zawsze są zwracane pierwsze znalezione. Nawet jak żądamy ich wielokrotnie. Jest to zgodne z założeniem, ale upierdliwe. Np.

<div id="info">
  <p>Tytuł</p>
  <p>Gatunek</p>
  <p>Rok produkcji<p>
</div>

Żądam div#info {p, p, p} i dostaję... [ 'Tytuł', 'Tytuł', 'Tytuł' ].
Może i poprawne tylko zupełnie nieprzydatne. Jak to opisać?

  • div#info {p, p+p, p+p+p}?
  • div#info {p, p:nth-child(2), p:nth-child(2)}?
  • Coś własnego?
  • Zmienić interpretację (to też ma konsekwencje) – dodać kolejność? Kolejność wszystkich czy tylko tych samych?

Pytania mnożą się jak króliki.

BTW. Ani tag + tag ani :nth-child nie są jeszcze zaimplementowane.

Pomocy!

EDIT: Drobiazgi w tym link do dokumentacji z roboczej gałęzi „altfix” w gałęzi master.

Dopieścić parseDOM()

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 dla Cherry
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:

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.