QBoard » Artificial Intelligence & ML » AI and ML - R » beautifulsoup add a tag inside a string

beautifulsoup add a tag inside a string

  • Any browser that encounter the text www.domain.com or http://domain.com/etc/ in a text section of some html will automatically translate it into <a href="http://www.domain.com">www.domain.com</a>; or <a href="http://domain.com/etc/">http://domain.com/etc/</a>; tag. I have to clean-up and verify some texts like this and do this replacement automatically, but the problem is that i can't insert new tags into an element's string.

    #!/usr/bin/python
    # -*- coding: utf8
    import re
    from bs4 import BeautifulSoup as bs
    
    def html_content_to_soup(data):
        soup = bs(data, "html5lib")
        soup.html.unwrap()
        soup.head.unwrap()
        soup.body.unwrap()
        return soup
    
    def create_tag(soup):
        def resubfunction(m):
            url = m.group(0)
    
            if not url.startswith("http://") and not url.startswith("https://"):
                _url = "http://%s" % url
            else:
                _url = url
    
            tag = soup.new_tag('a', href=_url)
            tag.string = url.replace(".", "[.]")
            return tag.prettify(formatter=None)
        return resubfunction
    
    def replace_vulnerable_text(soup, data):
        ex = r"(?i)\b((?:https?:(?:/{1,3}|[a-z0-9%])|[a-z0-9.\-]+[.](?:com|net|org|edu|gov|mil|aero|asia|biz|cat|coop|info|int|jobs|mobi|museum|name|post|pro|tel|travel|xxx|ac|ad|ae|af|ag|ai|al|am|an|ao|aq|ar|as|at|au|aw|ax|az|ba|bb|bd|be|bf|bg|bh|bi|bj|bm|bn|bo|br|bs|bt|bv|bw|by|bz|ca|cc|cd|cf|cg|ch|ci|ck|cl|cm|cn|co|cr|cs|cu|cv|cx|cy|cz|dd|de|dj|dk|dm|do|dz|ec|ee|eg|eh|er|es|et|eu|fi|fj|fk|fm|fo|fr|ga|gb|gd|ge|gf|gg|gh|gi|gl|gm|gn|gp|gq|gr|gs|gt|gu|gw|gy|hk|hm|hn|hr|ht|hu|id|ie|il|im|in|io|iq|ir|is|it|je|jm|jo|jp|ke|kg|kh|ki|km|kn|kp|kr|kw|ky|kz|la|lb|lc|li|lk|lr|ls|lt|lu|lv|ly|ma|mc|md|me|mg|mh|mk|ml|mm|mn|mo|mp|mq|mr|ms|mt|mu|mv|mw|mx|my|mz|na|nc|ne|nf|ng|ni|nl|no|np|nr|nu|nz|om|pa|pe|pf|pg|ph|pk|pl|pm|pn|pr|ps|pt|pw|py|qa|re|ro|rs|ru|rw|sa|sb|sc|sd|se|sg|sh|si|sj|Ja|sk|sl|sm|sn|so|sr|ss|st|su|sv|sx|sy|sz|tc|td|tf|tg|th|tj|tk|tl|tm|tn|to|tp|tr|tt|tv|tw|tz|ua|ug|uk|us|uy|uz|va|vc|ve|vg|vi|vn|vu|wf|ws|ye|yt|yu|za|zm|zw)/)(?:[^\s()<>{}\[\]]+|\([^\s()]*?\([^\s()]+\)[^\s()]*?\)|\([^\s]+?\))+(?:\([^\s()]*?\([^\s()]+\)[^\s()]*?\)|\([^\s]+?\)|[^\s\`!()\[\]{};:\'\".,<>?ÂŤÂťââââ])|(?:(?<!@)[a-z0-9]+(?:[.\-][a-z0-9]+)*[.](?:com|net|org|edu|gov|mil|aero|asia|biz|cat|coop|info|int|jobs|mobi|museum|name|post|pro|tel|travel|xxx|ac|ad|ae|af|ag|ai|al|am|an|ao|aq|ar|as|at|au|aw|ax|az|ba|bb|bd|be|bf|bg|bh|bi|bj|bm|bn|bo|br|bs|bt|bv|bw|by|bz|ca|cc|cd|cf|cg|ch|ci|ck|cl|cm|cn|co|cr|cs|cu|cv|cx|cy|cz|dd|de|dj|dk|dm|do|dz|ec|ee|eg|eh|er|es|et|eu|fi|fj|fk|fm|fo|fr|ga|gb|gd|ge|gf|gg|gh|gi|gl|gm|gn|gp|gq|gr|gs|gt|gu|gw|gy|hk|hm|hn|hr|ht|hu|id|ie|il|im|in|io|iq|ir|is|it|je|jm|jo|jp|ke|kg|kh|ki|km|kn|kp|kr|kw|ky|kz|la|lb|lc|li|lk|lr|ls|lt|lu|lv|ly|ma|mc|md|me|mg|mh|mk|ml|mm|mn|mo|mp|mq|mr|ms|mt|mu|mv|mw|mx|my|mz|na|nc|ne|nf|ng|ni|nl|no|np|nr|nu|nz|om|pa|pe|pf|pg|ph|pk|pl|pm|pn|pr|ps|pt|pw|py|qa|re|ro|rs|ru|rw|sa|sb|sc|sd|se|sg|sh|si|sj|Ja|sk|sl|sm|sn|so|sr|ss|st|su|sv|sx|sy|sz|tc|td|tf|tg|th|tj|tk|tl|tm|tn|to|tp|tr|tt|tv|tw|tz|ua|ug|uk|us|uy|uz|va|vc|ve|vg|vi|vn|vu|wf|ws|ye|yt|yu|za|zm|zw)\b/?(?!@)))"
        return re.sub(ex, create_tag(soup), data)
    
    if __name__ == "__main__":
        html = """<html><body>The website bbc.co.uk is down</body></html>"""
        soup = bs(html, "html5")
        for elem in soup.find_all(text=True):
            if elem.string is not None:
                elem.replace_with( html_content_to_soup(replace_vulnerable_text(soup, elem.string)))
    
        print unicode(soup)​

     

    Instead of the expected

    <html><body>The website <a href="http://bbc.co.uk">bbc[.]co[.]uk</a> is down</body></html>
    

    i'm getting

    <html><head></head><body>The website &lt;a href="http://bbc.co.uk"&gt; bbc[.]co[.]uk &lt;/a&gt; is down</body></html>
    

     

    EDIT: Edited the original question with the correct answer.

     
      August 25, 2021 3:01 PM IST
    0
  • A new tag can be created by calling BeautifulSoup's inbuilt function new_tag(). Inserting a new tag using the append() method : The new tag is appended to the end of the parent tag.
      January 3, 2022 2:06 PM IST
    0
  • import HTMLParser
    
    html_p = HTMLParser.HTMLParser()
    
    string = '<html><head></head><body>The website &lt;a href="http://bbc.co.uk"&gt; bbc[.]co[.]uk &lt;/a&gt; is down</body></html>'
    
    print html_p.unescape(string)

     

    it will give you the required output.

     
      August 27, 2021 12:58 PM IST
    0
  • I need a function which will return a soup from arbitrary html:

    def html_content_to_soup(data):
        soup = bs(data, "html5lib")
        soup.html.unwrap()
        soup.head.unwrap()
        soup.body.unwrap()
        return soup

     

    Afterwards, we get:

    elem.replace_with( html_content_to_soup(replace_vulnerable_text(soup, elem.string)) )
    

     

    This produces the required content:

    <html><head></head><body>The website <a href="http://bbc.co.uk">bbc[.]co[.]uk</a> is down</body></html>
    
      September 1, 2021 1:52 PM IST
    0