У меня есть приложение, которое продолжает сбой из-за того, что я считаю слишком большим количеством данных в списке.
Я вызываю данные XML из API и добавляю данные в список.Мне нужно сделать около 300K API-вызовов, что, по-моему, приводит к сбою приложения, потому что, когда я добавляю его в список, слишком много данных.
Ниже приведен код для вызова API и сохранения результатов в список.lst1
- это список идентификаторов, которые я передаю в API.Я должен принять во внимание, что если запрос http истекает или я могу создать механизм для очистки добавленного списка данных, то я могу перезапустить запросы с идентификатора, который я остановил с lst1
, который передается в API.URL-адрес.
import requests
import pandas as pd
import xml.etree.ElementTree as ET
from bs4 import BeautifulSoup
import time
from concurrent import futures
lst1=[1,2,3]
lst =[]
for i in lst1:
url = 'urlId={}'.format(i)
while True:
try:
xml_data1 = requests.get(url).text
print(xml_data1)
break
except requests.exceptions.RequestException as e:
print(e)
lst.append(xml_data1)
Я думаю, что если я смогу применить свою нижеприведенную функцию, чтобы распаковать xml в фрейм данных и выполнить необходимые манипуляции с фреймами данных, очистив при этом список добавленных данных lst
, чтобы он мог освободить память.Если это не так, я открыт для любых предложений о том, чтобы код или приложение не аварийно завершали работу с тем, что я считаю слишком большим количеством данных XML в списке:
def create_dataframe(xml):
soup = BeautifulSoup(xml, "xml")
# Get Attributes from all nodes
attrs = []
for elm in soup(): # soup() is equivalent to soup.find_all()
attrs.append(elm.attrs)
# Since you want the data in a dataframe, it makes sense for each field to be a new row consisting of all the other node attributes
fields_attribute_list = [x for x in attrs if 'Id' in x.keys()]
other_attribute_list = [x for x in attrs if 'Id' not in x.keys() and x != {}]
# Make a single dictionary with the attributes of all nodes except for the `Field` nodes.
attribute_dict = {}
for d in other_attribute_list:
for k, v in d.items():
attribute_dict.setdefault(k, v)
# Update each field row with attributes from all other nodes.
full_list = []
for field in fields_attribute_list:
field.update(attribute_dict)
full_list.append(field)
# Make Dataframe
df = pd.DataFrame(full_list)
return df
with futures.ThreadPoolExecutor() as executor: # Or use ProcessPoolExecutor
df_list = executor.map(create_dataframe, lst)
full_df = pd.concat(df_list)
print(full_df)
#final pivoted dataframe
final_df = pd.pivot_table(full_df, index='Id', columns='FieldTitle', values='Value', aggfunc='first').reset_index()