Skip to content

Instantly share code, notes, and snippets.

@wildmichael
Created January 31, 2018 19:28
Show Gist options
  • Save wildmichael/6f05794b02c2ebf386064294b191a037 to your computer and use it in GitHub Desktop.
Save wildmichael/6f05794b02c2ebf386064294b191a037 to your computer and use it in GitHub Desktop.
Small utility to easily create a document tree with BeautifulSoup4
from bs4 import BeautifulSoup, Tag
class Attribute(object):
def __init__(self, attrname, attrvalue):
'Initializes a new attribute.'
self._attrname = attrname
self._attrvalue = attrvalue
@property
def name(self):
'The attribute name'
return self._attrname
@property
def value(self):
'The attribute value'
return self._attrvalue
class TagFactory(object):
'A factory for `bs4.Tag` objects'
def __init__(self, soup):
'Initializes a new factory given a `bs4.BeautifulSoup`.'
self._soup = soup
@property
def soup(self):
'The `bs4.BeautifulSoup` instance.'
return self._soup
def __call__(self, tagname, *contents, **kwargs):
'Instantiates a `bs4.BeautifulSoup` instance given contents.'
tag = None
for c in contents:
if type(c) is Attribute:
if tag is not None:
raise ValueError('Attribute cannot follow content')
kwargs[c.name] = c.value
else:
if tag is None:
tag = self.soup.new_tag(tagname, **kwargs)
tag.append(c)
if tag is None:
tag = self.soup.new_tag(tagname, **kwargs)
return tag
soup = BeautifulSoup('')
f = TagFactory(soup)
html = f('html',
f('head',
f('meta', Attribute('foo', 'bar'))
),
f('body',
f('h1', 'Hello World!'),
f('p', 'This is a test.')
)
)
print(html.prettify())
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment