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:

shell
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:

python
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:

shell
python find_phone_numbers.py

Du 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:

json
{
"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.

Waterfall-søk som fortsetter etter manglende resultat og stopper når et telefonnummer blir funnet
Waterfall-søk som fortsetter etter manglende resultat og stopper når et telefonnummer blir funnet

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.

json
{
"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:

python
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.

Loading pricing…

Løs vanlige feil og gjenopprett en eksisterende oppgave

  • DATABLIST_API_KEY mangler: 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 headeren X-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 failed eller stopped: 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:

shell
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:

shell
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.