def rewrite_links(root, link_repl_func, resolve_base_href=False):
 from cssutils import replaceUrls, log, CSSParser
 log.setLevel(logging.WARN)
 log.raiseExceptions = False
 if resolve_base_href:
  resolve_base_href(root)
 for (el, attrib, link, pos) in iterlinks(root, find_links_in_css=False):
  new_link = link_repl_func(link.strip())
  if (new_link == link):
   continue
  if (new_link is None):
   if (attrib is None):
    el.text = ''
   else:
    del el.attrib[attrib]
   continue
  if (attrib is None):
   new = ((el.text[:pos] + new_link) + el.text[(pos + len(link)):])
   el.text = new
  else:
   cur = el.attrib[attrib]
   if ((not pos) and (len(cur) == len(link))):
    el.attrib[attrib] = new_link
   else:
    new = ((cur[:pos] + new_link) + cur[(pos + len(link)):])
    el.attrib[attrib] = new
 parser = CSSParser(raiseExceptions=False, log=_css_logger, fetcher=(lambda x: (None, None)))
 for el in root.iter(etree.Element):
  try:
   tag = el.tag
  except UnicodeDecodeError:
   continue
  if ((tag == XHTML('style')) and el.text and ((_css_url_re.search(el.text) is not None) or ('@import' in el.text))):
   stylesheet = parser.parseString(el.text, validate=False)
   replaceUrls(stylesheet, link_repl_func)
   repl = stylesheet.cssText
   if isbytestring(repl):
    repl = repl.decode('utf-8')
   el.text = (('\n' + repl) + '\n')
  if ('style' in el.attrib):
   text = el.attrib['style']
   if (_css_url_re.search(text) is not None):
    try:
     stext = parser.parseStyle(text, validate=False)
    except:
     continue
    replaceUrls(stext, link_repl_func)
    repl = stext.cssText.replace('\n', ' ').replace('\r', ' ')
    if isbytestring(repl):
     repl = repl.decode('utf-8')
    el.attrib['style'] = repl

def rewrite_links ( root , link_repl_func , resolve_base_href = False ) : from cssutils import replaceUrls , log , CSSParser log . setLevel ( logging . WARN ) log . raiseExceptions = False if resolve_base_href : resolve_base_href ( root ) for ( el , attrib , link , pos ) in iterlinks ( root , find_links_in_css = False ) : new_link = link_repl_func ( link . strip ( ) ) if ( new_link == link ) : continue if ( new_link is None ) : if ( attrib is None ) : el . text = '' else : del el . attrib [ attrib ] continue if ( attrib is None ) : new = ( ( el . text [ : pos ] + new_link ) + el . text [ ( pos + len ( link ) ) : ] ) el . text = new else : cur = el . attrib [ attrib ] if ( ( not pos ) and ( len ( cur ) == len ( link ) ) ) : el . attrib [ attrib ] = new_link else : new = ( ( cur [ : pos ] + new_link ) + cur [ ( pos + len ( link ) ) : ] ) el . attrib [ attrib ] = new parser = CSSParser ( raiseExceptions = False , log = _css_logger , fetcher = ( lambda x : ( None , None ) ) ) for el in root . iter ( etree . Element ) : try : tag = el . tag except UnicodeDecodeError : continue if ( ( tag == XHTML ( 'style' ) ) and el . text and ( ( _css_url_re . search ( el . text ) is not None ) or ( '@import' in el . text ) ) ) : stylesheet = parser . parseString ( el . text , validate = False ) replaceUrls ( stylesheet , link_repl_func ) repl = stylesheet . cssText if isbytestring ( repl ) : repl = repl . decode ( 'utf-8' ) el . text = ( ( '\n' + repl ) + '\n' ) if ( 'style' in el . attrib ) : text = el . attrib [ 'style' ] if ( _css_url_re . search ( text ) is not None ) : try : stext = parser . parseStyle ( text , validate = False ) except : continue replaceUrls ( stext , link_repl_func ) repl = stext . cssText . replace ( '\n' , ' ' ) . replace ( '\r' , ' ' ) if isbytestring ( repl ) : repl = repl . decode ( 'utf-8' ) el . attrib [ 'style' ] = repl
thin wrapper around lxmls rewrite_links() that prevents extra html markup from being produced when theres no root tag present in the input html .