Menu

Pomiędzy bitami

Techno, porno i duszno. Blog niezupełnie technologiczny.

Blox.pl - feed RSS dla pojedynczej kategorii

rozieblox

Wymaganiem udziału w konkuresie DSP2017 jest podanie feedu RSS zawierającego wyłącznie posty związane z konkursem. Blox.pl spłatał mi niemiłego figla i dał wybór - albo stary, paskudny wygląd, albo brak możliwości pobrania feedu RSS dla pojedynczej kategorii. Sprawę zgłosiłem, ale znając czasy realizacji stwierdziłem, że mam trzy możliwości: zrezygnować z DSP2017, postawić osobnego bloga specjalnie dla DSP2017 albo zrobić coś samemu.

Pierwsze dwie możliwości odrzuciłem. Jakoś nie widział mi się blog z 20 postami, kolejnego prowadzić mi się nie chce, a Blox ma swoje zalety i do porzucenia jeszcze nie dojrzałem. Spojrzałem co też mam do dyspozycji pod ręką, bo w pewne parsowanie feedu RSS bawiłem się już przy pomocy Perla (patrz zawartość mojego konta na blabler.pl). Niestety, stwierdziłem, że niezbyt się to nadaje do użytku.

Poza tym, przeszedłem na Pythona, więc pomyślałem o małej rozgrzewce. Pierwszym pomysłem było przeparsowanie całego feeda i złożenie RSS. Znalazłem przykłady parsowania XML z użyciem beautifulsoup4, z którego zresztą trochę wcześniej korzystałem. Wyciąganie zawartości poszczególnych postów poszło bardzo dobrze.

Stwierdziłem, że zamiast się bawić w tworzenie feedu kolejnym modułem, w ramach eksperymentu dodam przy pomocy chamskich printów nagłówki od XML. O dziwo zadziałało, Firefox widział coś, co wyglądało prawie jak oryginał. Jedynym problemem było kodowanie - zdecydowanie był problem z pl-znakami. Rzecz w tym, że Blox używa iso-8859-2, a Python wypluwa UTF-8. Wystarczyła szybka zmiana deklaracji kodowania w nagłówku XML i już było OK.

Kolejny problem wyszedł przy przepuszczeniu feeda przez validatory feedów RSS. Okazało się, że beautifulsoup4 zamienia wszystkie znaki w tagach na lowercase i - wierząc szybkiemu sprawdzeniu - nie ma prostego sposobu, by go od tego odwieść. Podjąłem próbę zamiany moduł na inny, ale szybko zrezygnowałem na rzecz brzydkich, ale skutecznych sedów na wyniku działania skryptu.

Na koniec zostało dodanie wywołania (z użyciem utworzonego na tę okoliczność virutalenv) do crona:

*/15 * * * * /home/rozie/dsp2017/bin/python /home/rozie/rss_from_category_blox.py 2>/dev/null | /bin/sed s'/pubdate/pubDate/g' | /bin/sed 's/lastbuilddate/lastBuildDate/g' > /tmp/dsp2017.xml && /bin/mv -f /tmp/dsp2017.xml /var/www/dsp2017.xml
*/15 * * * * /home/rozie/dsp2017/bin/python /home/rozie/rss_from_category_blox.py 2>/dev/null > /tmp/dsp2017.xml && /bin/mv -f /tmp/dsp2017.xml /var/www/dsp2017.xml

Całość wrzucam na GitHub, na wypadek, gdyby miało się komuś przydać.


UPDATE: Zgodnie z sugestią z komentarza, parsuję XML prawidłowo i pozbyłem się sed poprawiającego wyjście.

Komentarze (3)

Dodaj komentarz
  • Gość: [Sebastian] *.internetia.net.pl

    Problem z tagami jest, bo domyślnie BS4 traktuje feed jako HTML a nie XML. Żeby temu zaradzić trzeba by użyć np. lxml jako parsera w BS4 i wtedy:

    soup = BeautifulSoup(r.content, 'lxml-xml')

    Minus jest taki, że lxml jednak potrzebuje kompilacji podczas instalacji, więc to dodatkowe zależności.

  • rozieblox

    @Sebastian Masz rację. Nawet próbowałem robić coś w tym kierunku i nawet w dobrą stronę, ale nie zmieniłem r.text na r.content i ogólne błędy z związane lxml, za których przyczynę uznałem instalację jeszcze jakichś innych modułów. Wkrótce zaktualizuję repo i wpis. Dzięki! :-)

  • Gość: [Sebastian] *.internetia.net.pl

    Więcej info o tym co robi Response.text w requests: www.python-requests.org/en/latest/api/#requests.Response.text

© Pomiędzy bitami
Blox.pl najciekawsze blogi w sieci