Seite 1 von 1

Durch mehrere Seiten im API-Request loopen

Verfasst: Dienstag 5. Mai 2020, 12:16
von verano123
Hallo zusammen,

ich bin kein Entwickler, weshalb mir das anpassen/verstehen von Code etwas schwer fällt.

Ich habe eine API die ich Anspreche und mir ein JSON-Objekt zurück gibt, dass ich in eine JSON-Datei schreibe.
Das Problem hierbei ist aber, dass ich Informationen brauche, die auf mehreren URL's sind und ich gerne alles in ein JSON-File ablegen würde.

Code: Alles auswählen


from datetime import date
import requests
import boto3
import json
import os
import pandas as pd

# Connection
headers = {
    'Accept': 'application/json',
    'Authorization': 'XXX
}

response = requests.get('https://api.placetel.de/v2/call_center_calls?per_page=100', params={
    'date': today,
    ''page': 1

}, headers=headers)

CallCenterCalls = response.json()
Ich könnte hierbei den request mehrmals durchführen und bei

Code: Alles auswählen

'page': 1
einfach die Seitenzahl ändern, gerne hätte ich aber, dass er die Seitenanzahl selber durchloopt, bis die Einträge auf der Seite <100 sind.
Stackoverflow habe ich leider schon durchgesucht, aber verstehen tue ich die meisten Antworten leider nicht.

Vielleicht kennt sich ja jemand mit dem Problem aus und kann mir hier kurz weiterhelfen !
Danke

Re: Durch mehrere Seiten im API-Request loopen

Verfasst: Dienstag 5. Mai 2020, 17:30
von sls
Ein Anfang wäre doch eine while-Schleife zu schreiben in der `page` nach jeder Iteration inkrementiert wird. Gibt es irgendwo eine API-Beschreibung? Evtl. wird da Bulk unterstützt und was du möchtest ist so gar nicht notwendig? (Zu mal jeder Request immer was kostet)

Re: Durch mehrere Seiten im API-Request loopen

Verfasst: Mittwoch 6. Mai 2020, 08:04
von verano123
Guten Morgen,

eine while-Schleife mit inkrementieren nach jedem durchlaufen funktioniert leider nicht.
Bulk wird soweit unterstützt, dass pro Page max. 100 Einträge unterstützt werden.

Code: Alles auswählen

 per_page=100 
Wir haben c.a. 500-600 Anrufe täglich. D.h. ich muss durch X Seiten iterieren.

Eine Dokumentation dazu findet sich unter:
https://api.placetel.de/v2/docs/#placet ... all-center

Ich hab jetzt einen Workaround gemacht, indem ich die veraltete API anspreche https://www.placetel.de/hilfe/telefonanlage/api
Somit haben wir schonmal die Daten in unserem Warehouse.

Nichtsdestotrotz versuche ich weiterhin den Code dahingehend anzupassen, dass die API v2 benutzt werden kann.
Ich versuche später mal mit grequests was hinzubekommen.

https://pypi.org/project/grequests/

Re: Durch mehrere Seiten im API-Request loopen

Verfasst: Mittwoch 6. Mai 2020, 08:36
von Sirius3
verano123 hat geschrieben: Mittwoch 6. Mai 2020, 08:04 eine while-Schleife mit inkrementieren nach jedem durchlaufen funktioniert leider nicht.
Warum funktioniert das nicht?

Re: Durch mehrere Seiten im API-Request loopen

Verfasst: Mittwoch 6. Mai 2020, 08:52
von einfachTobi
Was passiert denn, wenn du den Request ohne Angabe der Ergebnisse pro Seite und Seitenzahl machst? Die sind ja gem. der Doku optional.

Code: Alles auswählen

...
response = requests.get('https://api.placetel.de/v2/call_center_calls',
    params={'date': '2020-05-06'},
    headers = headers)
...

Re: Durch mehrere Seiten im API-Request loopen

Verfasst: Mittwoch 6. Mai 2020, 09:51
von verano123
einfachTobi hat geschrieben: Mittwoch 6. Mai 2020, 08:52 Was passiert denn, wenn du den Request ohne Angabe der Ergebnisse pro Seite und Seitenzahl machst? Die sind ja gem. der Doku optional.

Code: Alles auswählen

...
response = requests.get('https://api.placetel.de/v2/call_center_calls',
    params={'date': '2020-05-06'},
    headers = headers)
...
Standartmäßig werden nur die ersten 25 Einträge ausgegeben.
Ich hatte mich mit den Entwicklern in Verbindung gesetzt. Pro Seite können nur 100 Einträge abgebildet werden. Wenn mehr Einträge erwartet werden, muss ich über die einzelnen Pages iterieren.

Wenn ich das ganze über eine while-schleife versuche umzusetzten:

Code: Alles auswählen

i = 1
while i <6

'page' : i+1
kommt folgender Fehler

Code: Alles auswählen

IndentationError: expected an indented block
Ich hatte das ganze auch als Array versucht:

Code: Alles auswählen

 i = [0,1,2,3,4,5] 
Hier nimmt er leider nur den letzten Array-Eintrag

Re: Durch mehrere Seiten im API-Request loopen

Verfasst: Mittwoch 6. Mai 2020, 10:21
von Sirius3
Ein IndentationError ist ja ein simpler Syntaxfehler. Zeig doch den gesamten Code, dann sieht man ziemlich schnell, was wo falsch eingerückt ist.

Re: Durch mehrere Seiten im API-Request loopen

Verfasst: Mittwoch 6. Mai 2020, 10:28
von einfachTobi
Deine Schleife ist nicht korrekt und hat einen Syntaxfehler. Die muss grundsätzlich so oder so ähnlich aussehen:

Code: Alles auswählen

headers = {
    'Accept': 'application/json',
    'Authorization': 'XXX
}
i = 0 #  oder beginnt die Seitenzählung bei 1?
call_center_calls = []
while i <= 10: #  Anzahl der Seiten
    response = requests.get('https://api.placetel.de/v2/call_center_calls?per_page=100',
        params={'date': today,
                         'page': i },
        headers=headers)
    call_center_calls.append(response.json())
    i += 1
Wobei ich eher davon ausgehe, dass du eine entsprechende Rückmeldung bekommst, wenn die Seite nicht existiert, weil nicht genügend Einträge vorhanden sind. Oder du bekommst eine leere Rückmeldung. Das müsstest du mal prüfen. Dann kannst du nämlich deine Schleife davon abhängig machen, ob noch Ergebnisse da sind.
Als "Pseudocode":

Code: Alles auswählen

CALLS_PER_PAGE = 100

def calls_left(response, per_page):
    if len(calls_left) == per_page:
        return True
    else:
        return False

i = 0 #  oder beginnt die Seitenzählung bei 1?
call_center_calls = []
while calls_left(response, CALLS_PER_PAGE):
    response = requests.get('https://api.placetel.de/v2/call_center_calls?per_page=CALLS_PER_PAGE',
        params={'date': today,
                         'page': i },
        headers=headers)
    call_center_calls.append(response.json())
    i += 1
Die Prüfung musst du natürlich an das entsprechende Merkmal anpassen. Hier war die Überlegung zu prüfen, ob die Anzahl zurückgegebener Calls den Calls per Page entspricht.

Re: Durch mehrere Seiten im API-Request loopen

Verfasst: Mittwoch 6. Mai 2020, 12:06
von verano123
einfachTobi hat geschrieben: Mittwoch 6. Mai 2020, 10:28 Deine Schleife ist nicht korrekt und hat einen Syntaxfehler. Die muss grundsätzlich so oder so ähnlich aussehen:

Code: Alles auswählen

headers = {
    'Accept': 'application/json',
    'Authorization': 'XXX
}
i = 0 #  oder beginnt die Seitenzählung bei 1?
call_center_calls = []
while i <= 10: #  Anzahl der Seiten
    response = requests.get('https://api.placetel.de/v2/call_center_calls?per_page=100',
        params={'date': today,
                         'page': i },
        headers=headers)
    call_center_calls.append(response.json())
    i += 1

Ich habe den Code jetzt soweit angepasst. Anscheinend war ich einfach nicht in der Lage eine while-Schleife in Python richtig hinzubekommen !
Die ausgegebene JSON sieht gut aus. Wandel ich die jetzt in eine CSV um, kommt da nur Murks raus. Anscheinend wird da irgendwo etwas doppelt genommen. Wahrscheinlich für jeden Durchlauf die Struktur fürs JSON neu eingefügt.

Schauen wir mal ob unser Warehouse die JSON ordentlich verarbeiten kann.
Vielen Dank für die Hilfe !

Code: Alles auswählen

i = 1
CallCenterCalls = []

while i <= 5:  # Anzahl der Seiten
    response = requests.get('https://api.placetel.de/v2/call_center_calls?per_page=100', params={
        'date': today,
        'page': i

    }, headers=headers)
    CallCenterCalls.append(response.json())
    i += 1

with open('CallCenterCalls'+today+'.json', 'w') as fp:
    json.dump(CallCenterCalls, fp)