Du kan finne telefonnumre fra LinkedIn i Python ved å sende offentlige
profil-URL-er av typen linkedin.com/in/... til Datablists Waterfall Phone Finder API.
API-et sjekker aktuelle leverandører av telefondata i tur og orden og returnerer
numrene i internasjonalt format med landskode.
Denne veiledningen bruker Requests-biblioteket til å lage én komplett Python-integrasjon. Deretter bruker vi de samme resultatene til å opprette en lokal ringeliste som beholder navn, LinkedIn-URL og kundeansvarlig for hvert prospekt.
📌 Kort oppsummert
Bruk ett API til å finne telefonnumre fra en liste med offentlige LinkedIn-profil-URL-er, og lag deretter en lokal ringeliste med navn og kundeansvarlig for hvert prospekt. Waterfall Phone Finder prøver aktuelle leverandører i tur og orden og gjør numrene klare for teamets gjennomgang.
- Input: Prospektoppføringer med en offentlig LinkedIn-profil-URL.
- Output: En lokal ringeliste med internasjonale telefonnumre, landskoder, navn og kundeansvarlige.
💡 Foretrekker du en no-code-løsning? Bruk Datablists Waterfall Phone Finder til å finne telefonnumre fra LinkedIn-profil-URL-er uten å skrive kode.
Hvis du starter med navn i stedet for profil-URL-er, kan du først følge no-code-metoden fra navn til telefonnummer eller finne LinkedIn- profiler fra navn i Python.
Konfigurer Python, Requests og Datablist API-nøkkelen
I dette Python-eksempelet bruker jeg pakken requests. Opprett en prosjektmappe,
aktiver et virtuelt miljø, installer Requests og opprett skriptfilen:
mkdir waterfall-phone-lookup
cd waterfall-phone-lookup
python -m venv .venv
source .venv/bin/activate
python -m pip install requests
touch find_phone_numbers.py
export DATABLIST_API_KEY="your-api-key"Opprett en Personal API Key i Datablist-kontoen
din, og bruk den som DATABLIST_API_KEY. Tilgang til REST API er inkludert i
Growth-abonnementet. Senere i veiledningen går jeg gjennom hvor mange credits
vellykkede søk bruker.
Finn telefonnumre med én komplett Python-funksjon
Eksempelet bruker tre prospektoppføringer som du kan redigere. Hver oppføring har en
stabil prospect_id, et navn, en offentlig LinkedIn-URL og den kundeansvarlige som
skal gjennomgå resultatet:
- Florian Poullin på
https://www.linkedin.com/in/florianpoullin/ - Satya Nadella på
https://www.linkedin.com/in/satyanadella/ - Reid Hoffman på
https://www.linkedin.com/in/reidhoffman/
Bare den stabile ID-en og LinkedIn-URL-en må sendes til API-et. Navnet og den kundeansvarlige blir værende i den lokale kildeoppføringen. Slik blir forespørselen liten, samtidig som du beholder forretningsinformasjonen teamet trenger når resultatet er returnert.
Lim inn hele dette skriptet i find_phone_numbers.py:
import json
import os
import time
import uuid
import requests
def find_phone_numbers(prospects, api_key, settings):
"""Submit one phone lookup task, wait, and return every result."""
tasks_url = "https://api.datablist.com/v1/enrichments/tasks"
headers = {"X-API-Key": api_key}
inputs = [
{
"inputId": prospect["prospect_id"],
"data": {"profileUrl": prospect["linkedin_url"]},
}
for prospect in prospects
]
unique_id = str(uuid.uuid4())
print(f"Task uniqueId: {unique_id}", flush=True)
payload = {
"enrichmentId": "waterfall-phone-finder",
"uniqueId": unique_id,
"settings": settings,
"inputs": inputs,
}
response = requests.post(tasks_url, headers=headers, json=payload)
response.raise_for_status()
task = response.json()
task_id = task["@id"]
task_url = f"{tasks_url}/{task_id}"
while task["status"] not in ("completed", "failed", "stopped"):
time.sleep(3)
response = requests.get(task_url, headers=headers)
response.raise_for_status()
task = response.json()
if task["status"] != "completed":
raise RuntimeError(
f"Task {task_id} {task['status']}: {task.get('error')}"
)
results = []
results_url = f"{task_url}/results"
params = {"limit": 100}
while True:
response = requests.get(results_url, headers=headers, params=params)
response.raise_for_status()
page = response.json()
results.extend(page["results"])
next_cursor = page["nextCursor"]
if next_cursor is None:
break
params["cursor"] = next_cursor
return results
if __name__ == "__main__":
api_key = os.environ.get("DATABLIST_API_KEY")
if not api_key:
raise SystemExit("Set DATABLIST_API_KEY before running this script.")
prospects = [
{
"prospect_id": "prospect-florian-poullin",
"name": "Florian Poullin",
"linkedin_url": "https://www.linkedin.com/in/florianpoullin/",
"account_owner": "Habib",
},
{
"prospect_id": "prospect-satya-nadella",
"name": "Satya Nadella",
"linkedin_url": "https://www.linkedin.com/in/satyanadella/",
"account_owner": "Florian",
},
{
"prospect_id": "prospect-reid-hoffman",
"name": "Reid Hoffman",
"linkedin_url": "https://www.linkedin.com/in/reidhoffman/",
"account_owner": "Habib",
},
]
settings = {"cacheAge": "30"}
phone_results = find_phone_numbers(prospects, api_key, settings)
print(json.dumps(phone_results, indent=2, ensure_ascii=False))Kjør filen med:
python find_phone_numbers.pyDu kan også laste ned Datablists vedlikeholdte synkrone Requests-eksempel. Skriptet ovenfor følger den samme enkle rekkefølgen: Send inn én oppgave, vent på den og hent alle resultatsidene.
Send inn telefonsøket
Listeuttrykket gjør hvert kildeprospekt om til inputformatet API-et krever.
Din prospect_id blir til inputId, mens linkedin_url blir til
data.profileUrl. Bruk en offentlig personprofil med URL-banen
linkedin.com/in/.... Sales Navigator-URL-er støttes ikke av denne enrichments-funksjonen.
Funksjonen genererer uniqueId og skriver den ut før POST-kallet. Forespørselen
sender verdien sammen med enrichment-ID-en waterfall-phone-finder, cache-innstillingen
og inputdataene. En vellykket innsending returnerer HTTP 202 Accepted og oppgavens
@id, mens behandlingen fortsetter i bakgrunnen.
API-referansen for Waterfall Phone Finder viser gjeldende innstillinger, inputfelt, output, credits og begrensninger.
For ett prospekt har request body følgende format:
{
"enrichmentId": "waterfall-phone-finder",
"uniqueId": "generated-uuid",
"settings": {
"cacheAge": "30"
},
"inputs": [
{
"inputId": "prospect-florian-poullin",
"data": {
"profileUrl": "https://www.linkedin.com/in/florianpoullin/"
}
}
]
}Den offentlige profil-URL-en er inputen til søket. inputId er koblingsnøkkelen som
knytter resultatet til navnet og den kundeansvarlige i kildeoppføringen. Velg en ID
som er stabil i ditt eget system og unik i oppgaven.
Vent på bakgrunnsoppgaven
Requests-klienten blokkerer lokalt mens den sjekker oppgaven hvert tredje sekund.
Datablist-oppgaven kjører fortsatt i bakgrunnen. Når statusen blir completed, går
funksjonen videre til å hente resultatene. Statusen failed eller stopped utløser
en feil med oppgave-ID-en, slik at du kan undersøke den.
Hent alle resultatsidene
Resultatforespørselen ber om opptil 100 rader om gangen. Den fortsetter å hente sider
til nextCursor er null. Hvert resultat inneholder sin opprinnelige inputId, slik
at du kan koble det til riktig prospekt uten å være avhengig av rekkefølgen i svaret.
Slik finner den administrerte waterfall-prosessen telefonnumre
Eksempelet setter cacheAge til "30". Datablist sjekker først om det finnes et
gyldig resultat som er maksimalt 30 dager gammelt. Hvis et slikt resultat finnes,
kan API-et gjenbruke det. Innstillingen tillater et cache-treff, men garanterer det ikke.
Hvis profilen fortsatt ikke har gitt et resultat, prøver den administrerte waterfall- prosessen aktuelle leverandører av telefondata i tur og orden. Hvis en leverandør ikke returnerer et brukbart nummer, går oppføringen videre. Et brukbart nummer avslutter sekvensen for den aktuelle oppføringen.
Derfor fungerer waterfall på tvers av land og markeder
Datablist baserer seg ikke på én enkelt leverandør av telefondata. Leverandørene bruker ulike datasett, og dekningen varierer mellom land og markeder. Når én leverandør ikke har et telefonnummer, kan en annen finne det. Datablist administrerer disse leverandørene gjennom den samme API-integrasjonen.
For et salgsteam som bygger en ringeliste på tvers av flere markeder, betyr dette at færre prospekter faller bort når én leverandør ikke finner noe. Python-koden sender inn én oppgave og leser ett resultatformat, så du slipper å bygge og vedlikeholde en egen integrasjon for hver leverandør.
Sett cacheAge til "0" når workflowen spesifikt krever et nytt søk. Behold "30"
i eksempelet, slik at et gyldig cache-resultat kan gjenbrukes.
Les hele resultatet
Her er ett resultat for Florian Poullin. Telefonnumrene er maskert nedenfor.
{
"inputId": "prospect-florian-poullin",
"status": "success",
"outputs": {
"finderProvider": "wizleads",
"phoneNumber": "+33 • •• •• •• ••",
"phoneNumberCountry": "FR"
},
"creditsUsed": "500",
"error": null
}phoneNumber inneholder det internasjonale nummeret når dette er tilgjengelig.
Prefikset +33 og phoneNumberCountry: "FR" viser at det er et fransk nummer.
finderProvider er leverandøren som er oppgitt for dette resultatet. Raden brukte
500 credits, og error: null betyr at API-et ikke returnerte noen feil på radnivå.
Lag en kvalitetssikret ringeliste for salg
Når phone_results er tilgjengelig, kan du lage en lokal liste som salgsteamet kan
gjennomgå. Legg til denne blokken etter utskriften av resultatene i den samme filen.
Den gjenbruker de eksisterende resultatene og foretar ikke et nytt API-kall:
results_by_id = {
result["inputId"]: result
for result in phone_results
}
call_list = []
for prospect in prospects:
result = results_by_id.get(prospect["prospect_id"])
if not result or result["status"] != "success":
continue
phone_number = result.get("outputs", {}).get("phoneNumber")
if not phone_number:
continue
call_list_record = prospect.copy()
call_list_record["result"] = result
call_list.append(call_list_record)
print(json.dumps(call_list, indent=2, ensure_ascii=False))Resultatindeksen bruker inputId som koblingsnøkkel. Dermed forblir hvert resultat
knyttet til kildeoppføringen uten å være avhengig av plasseringen i listen. API-payloaden
inneholder ID-en og profil-URL-en til hvert prospekt, mens den opprinnelige prospects-
listen beholder navnet og den kundeansvarlige som trengs i ringelisten.
For Florians rad kobler prospect-florian-poullin det returnerte resultatet til de
opprinnelige feltene name, linkedin_url og account_owner. Teamet henter nummeret
og landskoden FR fra result.outputs. Hele API-objektet, inkludert status, credits
og feil, forblir vedlagt under result.
Løkken for ringelisten følger rekkefølgen i prospects. Den kopierer hvert inkluderte
prospekt før result legges til. Dermed forblir den opprinnelige kildelisten tilgjengelig
for rettelser eller en annen oppfølgingskanal.
En rad uten resultat, med feil eller uten telefonnummer blir værende i den uendrede
prospects-listen, men legges ikke til i call_list. Koden lager en lokal ringeliste
som salgsteamet kan gjennomgå.
Beregn kostnaden for Waterfall Phone Finder API
Hvert nye, ikke-cachede telefonnummer som standardprosessen finner, bruker 500 credits.
Et godkjent cache-resultat bruker 0 credits, og et søk uten resultat bruker også 0 credits.
Les creditsUsed på hver returnerte rad for å se det faktiske forbruket, i stedet for
å multiplisere alle innsendte profiler med 500.
Bruk denne formelen til planlegging:
nye telefonnumre funnet uten bruk av cache × 500 credits
Førti nye numre bruker 20 000 credits. Hundre nye numre bruker 50 000 credits. Med dagens grunnpris for påfylling i USD gir $20 deg 20 000 credits, så 500 credits tilsvarer $0,50. Growth-abonnementet som gir tilgang til REST API, kommer i tillegg. Se Datablist-priser for gjeldende abonnementer og credit-pakker.
Tenk deg for eksempel at 100 profiler gir 20 nye numre, 5 godkjente cachede numre og
75 søk uten treff. Det er de 20 nye numrene som faktureres, så søket bruker 10 000
credits. Ringelisten kan inneholde alle de 25 numrene som ble funnet. Skriv inn 20
i kalkulatoren, ikke alle de 100 inputene eller alle de 25 numrene som ble funnet.
Eksempelet viser hvordan kostnaden beregnes, ikke en forventet treffprosent.
Løs vanlige feil og gjenopprett en eksisterende oppgave
DATABLIST_API_KEYmangler: Skriptet stopper før det sender en forespørsel. Eksporter variabelen, og kjør filen på nytt.- API-et avviser nøkkelen:
raise_for_status()rapporterer HTTP-feilen. Kopier Personal API Key på nytt, og bekreft at forespørselen sender den i headerenX-API-Key. - Profil-URL-en støttes ikke: Erstatt en tom, feilformatert URL, bedrifts-URL eller
Sales Navigator-URL med en offentlig personprofil som bruker banen
linkedin.com/in/.... - Du har ikke nok credits: Kontroller kontosaldoen og tilgjengelige credits før du sender inn flere oppgaver.
- Oppgaven har status
failedellerstopped: Undersøk feilen, tilgjengelige resultater og credit-forbruket før du avgjør hva som fortsatt må kjøres. - En rad mangler resultat eller har en feil: Behold kildeprospektet for retting eller en annen oppfølgingskanal. Raden alene forklarer ikke hvilken leverandør, geografi eller synlighetsbegrensning som førte til utfallet.
Hvis POST-svaret går tapt, bruker du uniqueId som ble skrevet ut før innsendingen.
List opp oppgavene dine før du sender inn på nytt. Erstatt your-api-key i denne
forespørselen, og finn oppgaven der uniqueId samsvarer med den utskrevne verdien:
curl --get "https://api.datablist.com/v1/enrichments/tasks" \
--header "X-API-Key: your-api-key" \
--data-urlencode "enrichmentId=waterfall-phone-finder" \
--data-urlencode "limit=100"Hvis oppgaven ikke finnes på den første siden, følger du nextCursor i svaret fra
oppgavelisten. Kopier @id for riktig oppgave, erstatt TASK_ID nedenfor, og sjekk
statusen eller hent de eksisterende resultatene:
curl "https://api.datablist.com/v1/enrichments/tasks/TASK_ID" \
--header "X-API-Key: your-api-key"
curl --get "https://api.datablist.com/v1/enrichments/tasks/TASK_ID/results" \
--header "X-API-Key: your-api-key" \
--data-urlencode "limit=100"Dokumentasjonen for oppgave-API-et forklarer oppgavestatuser, paginering av resultater og hva som skjer ved avbrudd.
Neste steg
Du har nå én gjenbrukbar Requests-funksjon for offentlige LinkedIn-profil-URL-er og én sammenslåing basert på stabile ID-er som klargjør funne telefonnumre for salgsteamets gjennomgang.
Bytt ut eksemplene med et lite utvalg kvalifiserte prospekter. Behold de stabile ID-ene og kundeansvarlige, og gjennomgå hvert nummer før du sender den klargjorte listen videre til teamets ringeprosess. Start med et lite parti, slik at du kan kontrollere ID-koblingen og feltene som returneres. Hvis du trenger ikke-blokkerende parallellitet, kan du bruke det vedlikeholdte async HTTPX-eksempelet.


