Insert HTML tag in all HTML files in a folder in Python
<p>I'm new to python and trying a program to do the following:</p>

<ol>
<li><p>Open all folder and subfolders in a directory path</p></li>
<li><p>Identify the HTML files</p></li>
<li><p>Load the HTML in BeautifulSoup</p></li>
<li><p>Find the first body tag</p></li>
<li><p>If the body tag is immediately followed by &lt; Google Tag Manager> then continue</p></li>
<li><p>If not then add &lt; Google Tag Manager> code and save the file.</p></li>
</ol>

<p>I'm not able to scan all subfolders within each folder.
I'm not able to set seen() if &lt; Google Tag Manager> appears immediately after the body tag.
Any help to perform the above tasks is appreciated.</p>

<p>My code attempt is as follows:</p>

<pre><code>  import sys
  import os
  from os import path
  from bs4 import BeautifulSoup

  directory_path = '/input'

  files = [x for x in os.listdir(directory_path) if path.isfile(directory_path+os.sep+x)]

  for root, dirs, files in os.walk(directory_path):
      for fname in files:
      seen = set()
      a = directory_path+os.sep+fname
      if fname.endswith(".html"):
          with open(a) as f:
              soup = BeautifulSoup(f)
              for li in soup.select('body'):
                if li in seen:
                    continue
                else:
                    seen.add("&lt;!-- Google Tag Manager --&gt;&lt;noscript&gt;&lt;iframe src='//www.googletagmanager.com/ns.html?id=GTM-54QWZ8'height='0' width='0' style='display:none;visibility:hidden'&gt;&lt;/iframe&gt;&lt;/noscript&gt;&lt;script&gt;(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start': new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0], j=d.createElement(s),dl=l!='dataLayer'?'&amp;l='+l:'';j.async=true;j.src='//www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);})(window,document,'script','dataLayer','GTM-54QWZ8');&lt;/script&gt;&lt;!-- End Google Tag Manager â&gt;\n")
</code></pre>

<p>My take on it, might have some bugs:</p>

<p>edited to add: I have since realized that this code does not ensure <code>&lt;!-- Google Tag Manager --&gt;</code> is the first tag after <code>&lt;body&gt;</code>, instead it ensures it is the first comment after <code>&lt;body&gt;</code>. Which is not what the question asked for.</p>

<pre><code>import fnmatch
import os
from bs4 import BeautifulSoup, Comment
from HTMLParser import HTMLParser


def get_soup(filename):
  with open(filename, 'r') as myfile:
    data=myfile.read()
  return BeautifulSoup(data, 'lxml')


def write_soup(filename, soup):
  with open(filename, "w") as file:
    output = HTMLParser().unescape(soup.prettify())
    file.write(output)


def needs_insertion(soup):
  comments = soup.find_all(text=lambda text:isinstance(text, Comment))
  try:
    if comments[0] == ' Google Tag Manager ':
      return False  # has correct comment
    else:
      return True  # has comments, but not correct one
  except IndexError:
    return True  # has no comments


def get_html_files_in_dir(top_level_directory):
  matches = []
  for root, dirnames, filenames in os.walk(top_level_directory):
      for filename in fnmatch.filter(filenames, '*.html'):
          matches.append(os.path.join(root, filename))
  return matches


my_html_files_path = '/home/azrad/whateveryouneedhere'
for full_file_name in get_html_files_in_dir(my_html_files_path):
  soup = get_soup(full_file_name)

  if needs_insertion(soup):
    soup.body.insert(0, '&lt;!-- Google Tag Manager --&gt; &lt;!-- End Google Tag Manager --&gt;')
    write_soup(full_file_name, soup)
</code></pre>

python html beautifulsoup