text: import os
  import re
  import json
  import requests
  import unicodedata
  import pandas as pd
  from datetime import datetime
  
  
  SHEET_URL = "https://docs.google.com/spreadsheets/d/e/2PACX-1vTt0fy2RR0fMYkm71jftBCGeP3ehHPiKbhjINx9wVSuFMPZaQAM0rZLcAEmKEbhCbvjSPugStZnENgB/pubhtml?gid=73056877&single=true"
  
  
  def url_content(url):
      response = requests.get(url)
      if response.status_code == 200:
          return response.text
      raise Exception(f"Error, request responded with code {response.status_code}.")
  
  
  def extract_charts_json(text):
      def unescape(orig_x):
          x = orig_x.replace("\/", "/")
          x = x.encode("ISO-8859-1").decode('unicode_escape')
          x = x.replace("ª", " ordinal")
          x = x.replace("º", " ordinal")
          return x
  
      finds = re.findall(r"'chartJson': '([^']*)'", text)
      unescaped = [unescape(find) for find in finds]
      return unescaped
  
  
  def remove_non_ascii(text):
      return unicodedata.normalize("NFD", text).encode("ascii", "ignore").decode("utf-8")
  
  
  def data_from_json(json_info):
      try:
          title = json_info["options"]["title"]
      except KeyError:
          # Is empty block
          return None
      rows = json_info["dataTable"]["rows"]
  
      columns = None
  
      for row in rows:
          c = row["c"]
  
          if not columns:
              columns = [[] for _ in range(len(c))]
  
          for i in range(len(c)):
              value = c[i]["v"] if c[i] else None
              columns[i].append(value)
  
      col_names = ["x"]
      for i in range(1, len(columns)):  # x is fixed, start from 1
          col_names.append(f"y{i}")
  
      df = pd.DataFrame(columns, index=col_names).T
  
      title = title.strip().replace("EM COMPARAÇÃO A DUAS SEMANAS ANTERIORES (14 DIAS)", "14 dias")  # fix too long file names
      return {
          "title": title,
          "df": df,
      }
  
  
  def data_from_extracted(extracted):
      res = []
      for ext in extracted:
          as_json = json.loads(ext)
          data = data_from_json(as_json)
          if data:
              res.append(data)
      return res
  
  
  def scrap_to_dict(req):
      extracted = extract_charts_json(req)
      data = data_from_extracted(extracted)
  
      data.append({
          "title": "Ungrouped",
          "df": ungrouped_information(req),
      })
  
      titles = [d["title"] for d in data]
      assert len(titles) == len(set(titles)), "Titles not unique. Is there a duplicate?"
  
      return {d["title"]:d["df"] for d in data}
  
  
  def regex_html_class(text, find):
      # Yes, I am using regex to find html.
      # Yes, this should not be done.
      # See https://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags for why.
  
      return re.findall(r"<td class=\"" + find + "\"[^>]*>([^<>]*)<[^>]*>", text)
  
  
  def last_updated_date(req):
      # Yes, I am using regex to find html.
      # Yes, this should not be done.
      # See https://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags for why.
  
      dates = regex_html_class(req, "s5")
      assert len(dates) == 1, "Found more than one date. Aborting."
  
      hours = regex_html_class(req, "s6")
      assert len(hours) == 1, "Found more than one hours. Aborting."
  
      date = dates[0]
      hour = hours[0]
      year = datetime.now().strftime("%Y")
  
      formatted = f"{date}/{year}-{hour}"
      formatted = formatted.replace("/", "_").replace(":", "_")  # for valid name
      return formatted
  
  
  def ungrouped_information(req):
      labels = []
      values = []
  
      class_names = [
          ("s34", "s35"),
          ("s37", "s38"),
          ("s39", "s40"),
          ("s41", "s42"),
          ("s45", "s46"),
          ("s48", "s49"),
          ("s55", "s56"),
          ("s60", "s61"),  # must also edit the exception bellow.
          ("s62", "s63"),
      ]
  
      for class_name_label, class_name_value in class_names:
          label = regex_html_class(req, class_name_label)
          value = regex_html_class(req, class_name_value)
  
          if class_name_value == "s61" and len(value) == 2:  # exception, returns two values.
              value = [value[0]]
  
          assert len(label) == len(value), f"At classname_label {class_name_label}, classname_value {class_name_value}: different lens: {label} and {value}."
          labels.extend(label)
          values.extend(value)
  
      # Testes Realizados
      labels.append("Testes Realizados")
      values.append(regex_html_class(req, "s64")[0].replace(".", ""))
  
      # UTI
      # Proprias
      labels.append("UTI Proprias Pactuadas")
      values.append(regex_html_class(req, "s96")[0])
  
      labels.append("UTI Proprias Ocupadas")
      values.append(regex_html_class(req, "s98")[0])
  
      labels.append("UTI Proprias Disponiveis")
      values.append(regex_html_class(req, "s99")[0])
  
      labels.append("UTI Proprias Indisponiveis")
      values.append(regex_html_class(req, "s100")[0])
  
      # Conveniadas
      labels.append("UTI Coveniadas Pactuadas")
      values.append(regex_html_class(req, "s108")[0])
  
      labels.append("UTI Coveniadas Ocupadas")
      values.append(regex_html_class(req, "s109")[0])
  
      labels.append("UTI Coveniadas Disponiveis")
      values.append(regex_html_class(req, "s110")[0])
  
      labels.append("UTI Coveniadas Indisponiveis")
      values.append(regex_html_class(req, "s111")[0])
  
      # Leitos Clinicos
      # Proprias
      labels.append("Leitos Clinicos Proprios Pactuados")
      values.append(regex_html_class(req, "s108")[1])
  
      labels.append("Leitos Clinicos Proprios Ocupados")
      values.append(regex_html_class(req, "s109")[1])
  
      labels.append("Leitos Clinicos Proprios Disponiveis")
      values.append(regex_html_class(req, "s110")[1])
  
      labels.append("Leitos Clinicos Proprios Indisponiveis")
      values.append(regex_html_class(req, "s111")[1])
  
      # Conveniadas
      labels.append("Leitos Clinicos Coveniados Pactuados")
      values.append(regex_html_class(req, "s96")[1])
  
      labels.append("Leitos Clinicos Coveniados Ocupados")
      values.append(regex_html_class(req, "s98")[1])
  
      labels.append("Leitos Clinicos Coveniados Disponiveis")
      values.append(regex_html_class(req, "s99")[1])
  
      labels.append("Leitos Clinicos Coveniados Indisponiveis")
      values.append(regex_html_class(req, "s100")[1])
  
      # Internacoes
      labels.append("Internacoes Leitos Clinicos")
      values.append(regex_html_class(req, "s123")[0])
  
      labels.append("Internacoes UTI")
      values.append(regex_html_class(req, "s124")[0])
  
      labels = [remove_non_ascii(e) for e in labels]
  
      return pd.DataFrame([labels, values], index=["x", "y"]).T
  
  
  def main():
      out_folder = "csvs"
      if not os.path.isdir(out_folder):
          os.mkdir(out_folder)
  
      req = url_content(SHEET_URL)
      date = last_updated_date(req)
      scraped = scrap_to_dict(req)
  
      for title, df in scraped.items():
          folder = f"{out_folder}/{title}/"
          file = f"{folder}{title}@{date}.csv"
  
          if not os.path.isdir(folder):
              os.mkdir(folder)
  
          if not os.path.isfile(file):  # do not override it
              df.to_csv(file, index=False, sep=",", encoding="UTF-8")
  
  
  if __name__ == "__main__":
      def _time_now():
          return datetime.now().strftime('%d/%m/%Y %H:%M:%f')
  
      print(f"[{_time_now()}] Starting scrapper...")
      main()
      print(f"[{_time_now()}] Scrapper executed.")
  