Как итеративно анализировать и сохранять ответы XML, которые входят в одну строку?
Я делаю вызовы API, то есть извлекаю идентификаторы, каждый вызов представляет 10000 идентификаторов, и я могу получить только 10000 одновременно. Моя цель - сохранить каждый вызов XML в списке, чтобы автоматически подсчитать, сколько человек на платформе.
Проблема, с которой я сталкиваюсь, состоит из двух частей.
Каждый вызов приходит как объект ответа, объект ответа, когда я добавляю в список, добавляется в виде одной строки, поэтому я не могу подсчитать общее количество идентификаторов.
Чтобы получить список следующих 10000 идентификаторов, я должен использовать другой вызов API для получения информации о каждом идентификаторе, а также получить часть информации, называемую идентификатором веб-сайта, и использовать ее для вызова следующих 10000 из API в #1.
Я также хочу предотвратить дублирование идентификаторов в списке, но мне кажется, что это самая простая задача.
Вот мой код:
1
- Идентификаторы профиля звонка (каждый звонок возвращает 10000)
Добавить объект ответа 'r' в список 'lst'
запросы на импорт import xml.etree.ElementTree as и импорт pandas в виде pd из lxml import etree время импорта
lst = [] xml = ''' <?xml version="1.0" encoding="utf-8" ?> <YourMembership> <Version>2.25</Version> <ApiKey>*****</ApiKey> <CallID>009</CallID> <SaPasscode>*****</SaPasscode> <Call Method="Sa.People.All.GetIDs"> <Timestamp></Timestamp> <WebsiteID></WebsiteID> <Groups> <Code></Code> <Name></Name> </Groups> </Call> </YourMembership> ''' headers = {'Content-Type': 'application/x-www-form-urlencoded'} r = requests.post('https://api.yourmembership.com', data=xml, headers=headers) lst.append(r.text)
Результат вызова API
<YourMembership_Response>
<Sa.People.All.GetIDs>
<People>
<ID>1234567</ID>
</People>
</Sa.People.All.GetIDs>
</YourMembership_Response>
2
Я беру последний идентификатор из вызова API в #1 и вручную ввожу значение в вызов API ниже в тегах 'ID'.
xml_2 = ''' <?xml version="1.0" encoding="utf-8" ?> <YourMembership> <Version>2.25</Version> <ApiKey>****</ApiKey> <CallID>001</CallID> <SaPasscode>****</SaPasscode> <Call Method="Sa.People.Profile.Get"> <ID>1234567</ID> </Call> </YourMembership> ''' headers = {'Content-Type': 'application/x-www-form-urlencoded'} r_2 = requests.post('https://api.yourmembership.com', data=xml_2, headers=headers) print (r_2.text)
Результат вызова API:
<YourMembership_Response>
<ErrCode>0</ErrCode>
<ExtendedErrorInfo></ExtendedErrorInfo>
<Sa.People.Profile.Get>
<ID>1234567</ID>
<WebsiteID>7654321</WebsiteID>
</YourMembership_Response>
Я беру идентификатор веб-сайта и перезапускаю его в API Call #1 (пример) с заполненным тегом идентификатора веб-сайта, получая следующие 10000, пока не вернутся результаты:
xml = '''
<?xml version="1.0" encoding="utf-8" ?>
<YourMembership>
<Version>2.25</Version>
<ApiKey>*****</ApiKey>
<CallID>009</CallID>
<SaPasscode>*****</SaPasscode>
<Call Method="Sa.People.All.GetIDs">
<Timestamp></Timestamp>
<WebsiteID>7654321</WebsiteID>
<Groups>
<Code></Code>
<Name></Name>
</Groups>
</Call>
</YourMembership>
'''
headers = {'Content-Type': 'application/x-www-form-urlencoded'}
r = requests.post('https://api.yourmembership.com', data=xml, headers=headers)
lst.append(r.text)
Надеюсь, мой вопрос имеет смысл, и спасибо заранее.
1 ответ
Однажды я начал создавать что-то для обхода API, что звучит похоже на то, чего вы хотите достичь. Одно из различий в моем случае было то, что ответ пришел как json вместо xml, но это не должно иметь большого значения.
Не вижу в вашем вопросе доказательств того, что вы действительно используете возможности парсера xml. Посмотрите документы. Например, вы можете легко получить идентификационный номер из тех элементов, которые вы добавляете в список следующим образом:
xml_sample = """
<YourMembership_Response>
<Sa.People.All.GetIDs>
<People>
<ID>1234567</ID>
</People>
</Sa.People.All.GetIDs>
</YourMembership_Response>
"""
import xml.etree.ElementTree as ET
root = ET.fromstring(xml_sample)
print (root[0][0][0].text)
>>> '1234567'
Поэкспериментируйте, примените его в цикле к каждому элементу в списке или, возможно, вам повезет, и весь объект отклика будет анализироваться без необходимости просматривать вещи.
Теперь вы должны иметь возможность программно вместо того, чтобы вручную вводить это число в следующем бите кода.
Ваш XML для следующего раздела для идентификатора веб-сайта содержит неверную строку <Sa.People.Profile.Get>
Как только я вытащу его, его можно проанализировать:
xml_sample2 = """
<YourMembership_Response>
<ErrCode>0</ErrCode>
<ExtendedErrorInfo></ExtendedErrorInfo>
<ID>1234567</ID>
<WebsiteID>7654321</WebsiteID>
</YourMembership_Response>
"""
root2 = ET.fromstring(xml_sample2)
print (root2[3].text)
>>> '7654321'
Поэтому не уверен, что всегда есть недопустимая строка или вы забыли вставить что-либо, возможно, удалите эту строку с помощью регулярного выражения или чего-то еще, прежде чем применять xtree.
Рекомендую вам попробовать sqlite, чтобы помочь вам с взаимодействиями между 1 и 2. Я думаю, что это хорошо до полумиллиона строк, в противном случае вам нужно будет подключиться к правильной базе данных. Он сохраняет файл в вашем каталоге и имеет немного меньше времени на настройку и суету, как с правильной базой данных. Возможно, протестируйте концепцию с помощью sqlite и при необходимости перенесите ее в postgresql.
Вы можете сохранить любые полезные элементы из этого проанализированного xml-кода, который вам нравится, идентификатор пользователя, идентификатор веб-сайта, в таблицу и снова извлечь его для использования в другом разделе. Также нетрудно переходить назад и вперед из sqlite в pandas, если вам это нужно с pandas.read_sql и pandas.DataFrame.to_sql. Надеюсь, это поможет..