Egy médiafigyelési feladatokat végrehajtó Python szkript vázlata
Nevezhetjük úgy is, hogy rss letöltő és feldolgozó és html letöltő és feldolgozó.
A feledat lényege, hogy ismétlődő jelleggel letöltjük egy weboldal rss-ét, utána végighaladunk az egyes elemeken, letöltjük a linkelt html-t, abból pedig adatokat nyerünk ki és tárolunk. Így kell nekiállni:
Függőségek
RSS értelmező
pip install feedparser
HTML feldolgozó
pip install BeautifulSoup
A szkript
import datetime
import re
import sys
import bs4
import feedparser
import requests
feed: feedparser.FeedParserDict = feedparser.parse(sys.argv[1])
for entry in feed["entries"]:
link: str = entry.link
guid: str = entry.guid
title: str = entry.title
lead: str = entry.description
published: datetime.datetime = datetime.datetime(
*(entry.published_parsed[:6]))
response: requests.Response = requests.get(link)
soup: bs4.BeautifulSoup = bs4.BeautifulSoup(
response.content.decode("utf-8", errors="ignore"), "html.parser")
article_tag: bs4.element.Tag = soup.find(
"div", attrs={"class": "content"})
html_cleanup(article_tag)
article_text: str = prettify(article_tag)
article_author: str = soup.find("div", attrs={
"class": "info"
}).find("a").text
A segédfüggvények, amik kitakarítják a HTML-t, csak azokat a tag-eket és attribútumokat meghagyva, amik minimálisan szükségesek ahhoz, hogy a tartalom olvasható legyen.
def html_cleanup(tag: bs4.element.Tag) -> None:
"""
Kitakarítja a html kódot
A tag értéket ugye referenciaként vette át, úgyhogy visszatérési érték
nem kell.
"""
children = list(tag.recursiveChildGenerator())
for child in children:
try:
if (not child):
continue
# kommentek törlése
if (isinstance(child, bs4.element.Comment)):
child.replaceWith("")
continue
# a sima szöveg elemeket békén hagyjuk
if (isinstance(child, bs4.element.NavigableString)):
continue
# attribútumok törlése, kivéve href és src
for k in list(child.attrs.keys()):
if (k not in ("href", "src")):
del child[k]
# javascript és css törlése
if (child.name in ("style", "script")):
child.decompose()
# bizonyos tag-ek maradhatnak
elif (child.name in ("a", "em", "p", "h1", "h2", "h3", "h4", "h5",
"h6", "strong", "table", "td", "tr")):
pass
# képek átalakítása a képre mutató linkekre
elif child.name == "img":
child.replaceWith(
bs4.BeautifulSoup(
"{0}".format(child['src']),
"html.parser"))
# minden további html tag eltávolítása
else:
child.unwrap()
except Exception as e:
print("Error", e)
def prettify(tag: bs4.element.Tag) -> str:
"""
Szépen formázott html string
"""
soup = bs4.BeautifulSoup("{}".format(tag.decode_contents()),
"html.parser")
return (soup.prettify())
A legújabb, 3.9-es Python és a 5.2.1-es verziószámú feedparser nem biztos, hogy jóban lesznek egymással
Traceback (most recent call last): File "/tmp/tmp.py", line 6, in import feedparser File "/home/dark/morkpy_venv/lib/python3.9/site-packages/feedparser.py", line 93, in _base64decode = getattr(base64, 'decodebytes', base64.decodestring) AttributeError: module 'base64' has no attribute 'decodestring'
Az ideiglenes megoldás:
import base64
base64.decodestring = base64.decodebytes