Как итеративно анализировать и сохранять ответы XML, которые входят в одну строку?

Я делаю вызовы API, то есть извлекаю идентификаторы, каждый вызов представляет 10000 идентификаторов, и я могу получить только 10000 одновременно. Моя цель - сохранить каждый вызов XML в списке, чтобы автоматически подсчитать, сколько человек на платформе.

Проблема, с которой я сталкиваюсь, состоит из двух частей.

  1. Каждый вызов приходит как объект ответа, объект ответа, когда я добавляю в список, добавляется в виде одной строки, поэтому я не могу подсчитать общее количество идентификаторов.

  2. Чтобы получить список следующих 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. Надеюсь, это поможет..

Другие вопросы по тегам