I'm scraping some xml sites using beautifulSoup, and then storing the scraped data to a dataframe. The XML is usually consistently-formatted so the scraping works fine. But maybe 15% of the time, the data doesn't get saved to the dataframe because one of the prefixes is slightly different.
For example, when scraping these three URLs, the 2nd and 3rd ones gets stored to the dataframe without issue, whereas the 1st one doesn't.
from bs4 import BeautifulSoup
import requests
import pandas as pd
session = requests.Session()
# urls to loop through
form_urls = ['https://www.sec.gov/Archives/edgar/data/1418814/000141881220000017/vac13f021420.xml',
'https://www.sec.gov/Archives/edgar/data/820124/000095012320003895/408.xml',
'https://www.sec.gov/Archives/edgar/data/1067983/000095012320002466/form13fInfoTable.xml']
# Create dataframe and set columns to match XML doc
cols = ['nameOfIssuer', 'titleOfClass', 'cusip', 'value', 'sshPrnamt',
'sshPrnamtType', 'putCall', 'investmentDiscretion',
'otherManager', 'Sole', 'Shared', 'None']
res_df = pd.DataFrame(columns=cols)
# Iterate over URLs
for form_url in form_urls:
data = []
soup = BeautifulSoup(session.get(form_url).content, 'lxml')
print(soup)
for info_table in soup.find_all(['ns1:infotable', 'infotable']):
row = []
for col in cols:
d = info_table.find([col.lower(), 'ns1:' + col.lower()])
row.append(d.text.strip() if d else 'NaN')
data.append(row)
url_df = pd.DataFrame(data, columns=cols)
res_df = res_df.append(url_df, ignore_index=True)
print(res_df)
So how can I make the scraper more flexible in case the prefix is in an unexpected format (e.g., maybe it's an empty string or some other combination of uppercase and lower case letters and numbers)?