HTML-filtering in Python: verschil tussen versies

Uit De Vliegende Brigade
Naar navigatie springen Naar zoeken springen
Regel 46: Regel 46:
 
<h1> Hello, <strong>world</strong></h1>
 
<h1> Hello, <strong>world</strong></h1>
 
  Hello, world
 
  Hello, world
 +
</pre>
 +
 +
== Voorbeeld: Selectief filter ==
 +
 +
Hier is de truuk, dat ''sommige'' tags behouden moeten worden. Waarschijnlijk is dit geen erg mooi programmeervoorbeeld, maar het werkt wel:
 +
 +
<pre>
 +
#! /usr/bin/python3
 +
#
 +
# parser-03.py - Jan. 2019
 +
##############################################################################
 +
#
 +
from html.parser import HTMLParser
 +
 +
class MyHTMLParser(HTMLParser):
 +
 +
    def handle_starttag(self, tag, attrs):
 +
        #
 +
        # Starttags that need to be preserved or transformed
 +
        ####################################################
 +
        #
 +
        if tag=="br": self.s_output=self.s_output+"<br>"
 +
        if tag=="ul": self.s_output=self.s_output+"<ul>"
 +
        if tag=="li": self.s_output=self.s_output+"<li>"
 +
 +
    def handle_endtag(self, tag):
 +
        #
 +
        # Endtags that need to be preserved or transformed
 +
        ####################################################
 +
        #
 +
        # print("Encountered an end tag :", tag)
 +
        #
 +
        if tag=="title": self.s_output=self.s_output+"<br>"
 +
        if tag=="h1": self.s_output=self.s_output+"<br>"
 +
        if tag=="h2": self.s_output=self.s_output+"<br>"
 +
        if tag=="h3": self.s_output=self.s_output+"<br>"
 +
        if tag=="ul": self.s_output=self.s_output+"</ul>"
 +
 +
    def handle_data(self, data):
 +
        #
 +
        # Incorporate all actual data
 +
        ####################################################
 +
        #
 +
        # print("Encountered some data  :", data)
 +
        #
 +
        self.s_output=self.s_output+data
 +
 +
    def __init__(self):
 +
        # print("Dit is de __init__-functie")
 +
        self.reset()
 +
        self.strict = False
 +
        self.convert_charrefs= True
 +
        self.s_output = ""
 +
 +
    def return_output(self):
 +
        #
 +
        # Some postprocessing + return parsed string
 +
        ####################################################
 +
        #
 +
        # * Maybe convert e.g. "<br> " to "<br>"
 +
        #
 +
        return ''.join(self.s_output)
 +
 +
 +
##############################################################################
 +
#
 +
s_input="<html><head><title>Title-data</title></head><body><h1>H1-title</h1>Gewone tekst met &uuml;mlaut en break<br> Gewone tekst<ul><li>LI-Item a<li>LI-Item 2</ul></body></html>"
 +
print(" ")
 +
print("######################################")
 +
print(s_input)
 +
 +
parser = MyHTMLParser()
 +
parser.feed(s_input)
 +
print(parser.return_output())
 
</pre>
 
</pre>
  

Versie van 14 jan 2019 14:13

HTMLParser-library

Er zijn meer wegen die naar Rome leiden, maar de eerste weg die ik tegenkwam, was in de gedaante van de HTMLParser-library.

De HTMLParser-library (of -module) defineert een klasse HTMLParser waarmee je HTML kunt parsen. Je voert 'm HTML-code, en hij roept diverse handler method aan. Die handler methods moet je overriden om ze te laten doen wat je wilt dat ze doen. De klasse kent handler methods en 'gewone' methods.

Eerste voorbeeld

Gebaseerd op [1]:

#! /usr/bin/python3
#
# parser-01.py - Jan. 2019
##############################################################################
#
from html.parser import HTMLParser

class MLStripper(HTMLParser):
    def __init__(self):
        self.reset()
        self.strict = False
        self.convert_charrefs= True
        self.fed = []
    def handle_data(self, d):
        self.fed.append(d)
    def get_data(self):
        return ''.join(self.fed)

def strip_tags(html):
    s = MLStripper()
    s.feed(html)   # Feed is een HTMLParser class-method/function
    return s.get_data()

##############################################################################
#
s="<h1> Hello, <strong>world</strong></h1>"
o=strip_tags(s)
print(s)
print(o)

Output:

<h1> Hello, <strong>world</strong></h1>
 Hello, world

Voorbeeld: Selectief filter

Hier is de truuk, dat sommige tags behouden moeten worden. Waarschijnlijk is dit geen erg mooi programmeervoorbeeld, maar het werkt wel:

#! /usr/bin/python3
#
# parser-03.py - Jan. 2019
##############################################################################
#
from html.parser import HTMLParser

class MyHTMLParser(HTMLParser):

    def handle_starttag(self, tag, attrs):
        #
        # Starttags that need to be preserved or transformed
        ####################################################
        #
        if tag=="br": self.s_output=self.s_output+"<br>"
        if tag=="ul": self.s_output=self.s_output+"<ul>"
        if tag=="li": self.s_output=self.s_output+"<li>"

    def handle_endtag(self, tag):
        #
        # Endtags that need to be preserved or transformed
        ####################################################
        #
        # print("Encountered an end tag :", tag)
        #
        if tag=="title": self.s_output=self.s_output+"<br>"
        if tag=="h1": self.s_output=self.s_output+"<br>"
        if tag=="h2": self.s_output=self.s_output+"<br>"
        if tag=="h3": self.s_output=self.s_output+"<br>"
        if tag=="ul": self.s_output=self.s_output+"</ul>"

    def handle_data(self, data):
        #
        # Incorporate all actual data
        ####################################################
        #
        # print("Encountered some data  :", data)
        #
        self.s_output=self.s_output+data

    def __init__(self):
        # print("Dit is de __init__-functie")
        self.reset()
        self.strict = False
        self.convert_charrefs= True
        self.s_output = ""

    def return_output(self):
        #
        # Some postprocessing + return parsed string
        ####################################################
        #
        # * Maybe convert e.g. "<br> " to "<br>"
        #
        return ''.join(self.s_output)


##############################################################################
#
s_input="<html><head><title>Title-data</title></head><body><h1>H1-title</h1>Gewone tekst met ümlaut en break<br> Gewone tekst<ul><li>LI-Item a<li>LI-Item 2</ul></body></html>"
print(" ")
print("######################################")
print(s_input)

parser = MyHTMLParser()
parser.feed(s_input)
print(parser.return_output())

Zie ook

Bronnen