I want the function to take as an input json file containing html_body with its corresponding url and return list of tuples containing headers and their corresponding url (so could be tuple with one item as a list of the headers).
So far I have been able to do so, but I'm missing some headers and more over, I'm sure that this code can be improved.
Commented out possible extensions for <h2>
headers extraction, and a different regex pattern I tried.
A taste of the source:
[["<body class=\" catalog-category-view categorypath-sale-html category-sale\">\n<script type=\"text/javascript\">\n//<![CDATA[\nif (typeof(Varien.searchForm) !== 'undefined') {\n Varien.searchForm.prototype._selectAutocompleteItem = function(element) {\n var link = element.down();\n if (link && link.tagName == 'A') {\n setLocation(link.href);\n } else {\n if (element.title){\n this.field.value = element.title;\n }\n this.form.submit();\n }\n };\n Varien.searchForm.prototype.initAutocomplete = function(url, destinationElement) {\n new Ajax.Autocompleter(\n this.field,\n destinationElement,\n url,\n {\n paramName: this.field.name,\n method: 'get',\n minChars: 2,\n frequency: .3,\n updateElement: this._selectAutocompleteItem.bind(this),\n onShow : function(element, update) {\n if(!update.style.position || update.style.position=='absolute') {\n update.style.position = 'absolute';\n Position.clone(element, update, {\n setHeight: false,\n offsetTop: element.offsetHeight\n });\n }\n Effect.Appear(update,{duration:0});\n }\n\n }\n );\n };\n Autocompleter.Base.prototype.markPrevious = function() {\n if (this.index > 0) {\n this.index--;\n } else {\n this.index = this.entryCount - 1;\n }\n var entry = this.getEntry(this.index);\n if (entry.select('a').length === 0) {\n this.markPrevious(); // Ignore items that don't have link\n }\n };\n Autocompleter.Base.prototype.markNext = function() {\n if (this.index < this.entryCount - 1) {\n
Code:
from pandas import DataFrame, Series
from tqdm import tqdm
import html5lib
import re
from bs4 import BeautifulSoup
def get_headers_from_json(local_path):
"""
The function takes a json file with html_body and returns a list of headers.
It parses the headers, based on tags starting with 'h'.
It also parses urls and return them in a tuple: (headers, url)
"""
data = json.loads(open(local_path).read())
pattern = "h1" # | h2 | h3"
# pattern = re.compile("^(?!.*(href)).*^h", re.IGNORECASE)
headers_urls = []
all_headers = []
for x in tqdm(data):
soup = BeautifulSoup(x[0], 'html.parser')
html_headers = soup.find_all(re.compile(pattern))
all_headers.append(html_headers)
url = x[1]
tuple_title_url = all_headers, url
headers_urls.append(tuple_title_url)
return headers_urls
PS - I checked the following links but couldn't find a great solution: HTML tag encoder HTML parsing algorithm for extracting <a> tags Scraping HTML using Beautiful Soup