import demistomock as demisto # noqa: F401 from bs4 import BeautifulSoup from CommonServerPython import * # noqa: F401 def extract_html_table(html, indexes): soup = BeautifulSoup(html, "html.parser") tables = [] for index, tab in enumerate(soup.find_all("table")): if len(indexes) > 0 and index not in indexes and str(index) not in indexes: continue table: Union[list, dict] = [] headers = [] # Check if there are headers and use them try: for th in tab.find_all("th"): # type: ignore headers.append(th.text) for tr in tab.find_all("tr"): # type: ignore tds = tr.find_all("td") # This is a data row and not header row if len(tds) > 0: # Single value in a table - just create an array of strings ignoring header if len(tds) == 1: table.append(tds[0].text) # type: ignore[union-attr] # If there are 2 columns and no headers, # treat as key-value (might override values if same key in first column) elif len(tds) == 2 and len(headers) == 0: if type(table) is list: table = {} # type: ignore table[tds[0].text] = tds[1].text # type: ignore[call-overload] else: row = {} if len(headers) > 0: for i, td in enumerate(tds): row[headers[i]] = td.text else: for i, td in enumerate(tds): row["cell" + str(i)] = td.text if isinstance(table, list): # type: ignore[arg-type] table.append(row) except Exception as e: demisto.debug(f"Failed to extract table: {e}") if len(table) > 0: tables.append(table) if len(tables) > 0: return { "Type": entryTypes["note"], "Contents": f"Found {len(tables)} tables in HTML.", "ContentsFormat": formats["text"], "EntryContext": {"HTMLTables": tables if len(tables) > 1 else tables[0]}, } else: return "Did not find tables in HTML." def main(): html = demisto.getArg("html") indexes = argToList(demisto.getArg("indexes")) demisto.results(extract_html_table(html, indexes)) if __name__ in ["__main__", "builtin", "builtins"]: main()