Du kan finde telefonnumre fra LinkedIn i Python ved at sende offentlige linkedin.com/in/...-profilwebadresser til Datablists Waterfall Phone Finder API. API'et tjekker relevante udbydere af telefondata i rækkefølge og returnerer fundne numre i internationalt format med landekode.

Denne guide bruger Requests-biblioteket til at bygge én komplet Python-integration. Derefter genbruger vi de samme resultater til at oprette en lokal opkaldsliste, der bevarer hver prospects navn, LinkedIn-URL og account owner.

📌 Kort fortalt

Brug ét API til at finde telefonnumre fra en liste over offentlige LinkedIn-profiler, og opret derefter en lokal opkaldsliste med navn og account owner for hver prospect. Waterfall Phone Finder afprøver relevante udbydere i rækkefølge og gør de fundne numre klar til teamets gennemgang.

  • Input: Prospect-data med en offentlig LinkedIn-profil-URL.
  • Output: En lokal opkaldsliste med fundne internationale telefonnumre, landekoder, navne og account owners.

💡 Foretrækker du en no-code-løsning? Brug Datablists Waterfall Phone Finder til at finde telefonnumre fra LinkedIn-profiler uden at skrive kode.

Hvis du starter med navne i stedet for profil-URL'er, skal du først følge vores no-code-workflow fra navn til telefonnummer eller finde LinkedIn-profiler fra navne med Python.

Konfigurer Python, Requests og din Datablist API key

I dette Python-eksempel bruger jeg pakken requests. Opret en projektmappe, aktivér et virtuelt miljø, installer Requests, og opret scriptfilen:

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"

Opret en Personal API Key på din Datablist-konto, og brug den som DATABLIST_API_KEY. Adgang til REST API er en funktion i Growth-abonnementet. Senere i guiden gennemgår jeg, hvor mange credits de vellykkede opslag bruger.

Find telefonnumre med én komplet Python-funktion

Eksemplet bruger tre prospect-poster, som du kan redigere. Hver post har et stabilt prospect_id, et navn, en offentlig LinkedIn-URL og den account owner, der skal gennemgå 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/

Kun det stabile ID og LinkedIn-URL'en skal sendes til API'et. Navnet og account owner bliver i din lokale kildepost. Denne opdeling holder lookup-requesten lille og bevarer samtidig de forretningsoplysninger, som teamet skal bruge, når resultatet er kommet retur.

Indsæt hele dette script 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))

Kør filen med:

shell
python find_phone_numbers.py

Du kan også downloade Datablists vedligeholdte synkrone Requests-eksempel. Scriptet ovenfor følger den samme enkle rækkefølge: Indsend én task, vent på den, og hent alle resultatsider.

Indsend telefonopslaget

List comprehension-udtrykket omdanner hver prospect fra kildedataene til API'ets inputformat. Dit prospect_id bliver til inputId, mens linkedin_url bliver til data.profileUrl. Brug en offentlig personprofil med stien linkedin.com/in/.... Sales Navigator-URL'er understøttes ikke af denne enrichment.

Funktionen genererer et uniqueId og udskriver det før POST-requesten. Requesten sender værdien sammen med enrichment-ID'et waterfall-phone-finder, cache-indstillingen og dine inputs. En vellykket indsendelse returnerer HTTP 202 Accepted og et task-@id, mens behandlingen fortsætter i baggrunden.

API-referencen til Waterfall Phone Finder viser de aktuelle indstillinger, inputfelter, outputs, credits og grænser.

For én prospect har request body denne struktur:

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 er input til opslaget. inputId er den join key, der forbinder resultatet med navnet og account owner i din kildepost. Vælg et ID, der er stabilt i dit eget system og unikt inden for tasken.

Vent på tasken i baggrunden

Requests-klienten blokerer lokalt, mens den tjekker tasken hvert tredje sekund. Datablist-tasken kører fortsat i baggrunden. Når dens status bliver completed, går funktionen videre til at hente resultaterne. Statussen failed eller stopped udløser en fejl med task-ID'et, så du kan undersøge den.

Hent alle resultatsider

Resultatrequesten henter op til 100 rækker ad gangen. Den fortsætter med at hente sider, indtil nextCursor er null. Hvert resultat indeholder sit oprindelige inputId, så du kan knytte det til den rigtige prospect uden at være afhængig af rækkefølgen i svaret.

Sådan finder den administrerede waterfall et telefonnummer

Eksemplet sætter cacheAge til "30". Datablist undersøger først, om der findes et relevant resultat, som højst er 30 dage gammelt. Hvis det findes, kan API'et genbruge det. Indstillingen tillader et cache-hit, men garanterer ikke et.

Hvis profilen stadig ikke er løst, afprøver den administrerede waterfall relevante udbydere af telefondata i rækkefølge. Returnerer en udbyder ikke et brugbart nummer, går posten videre. Et brugbart nummer stopper rækkefølgen for den pågældende post.

Waterfall-telefonopslag fortsætter efter et tomt resultat og stopper, når der findes et telefonnummer
Waterfall-telefonopslag fortsætter efter et tomt resultat og stopper, når der findes et telefonnummer

Derfor virker waterfall på tværs af lande og markeder

Datablist er ikke afhængig af én enkelt udbyder af telefondata. Udbyderne bruger forskellige datasæt, og deres dækning varierer fra land til land og marked til marked. Når én udbyder ikke har et telefonnummer, kan en anden måske finde det. Datablist administrerer alle udbyderne gennem den samme API-integration.

For et salgsteam, der bygger en opkaldsliste på tværs af flere markeder, betyder det, at færre prospects bliver sorteret fra, blot fordi én udbyder ikke finder et resultat. Din Python-kode indsender én task og læser ét resultatformat, så du slipper for at bygge og vedligeholde en separat integration til hver udbyder.

Sæt cacheAge til "0", når dit workflow specifikt kræver et nyt opslag. Behold "30" i eksemplet, så et relevant cachelagret resultat kan genbruges.

Læs hele resultatet

Her er et resultat for Florian Poullin. Telefonnumrene er maskeret nedenfor.

json
{
"inputId": "prospect-florian-poullin",
"status": "success",
"outputs": {
"finderProvider": "wizleads",
"phoneNumber": "+33 • •• •• •• ••",
"phoneNumberCountry": "FR"
},
"creditsUsed": "500",
"error": null
}

phoneNumber indeholder det internationale nummer, når et sådant er tilgængeligt. Præfikset +33 og phoneNumberCountry: "FR" viser, at det er et fransk nummer.

finderProvider er den finder, der er angivet for resultatet. Rækken brugte 500 credits, og error: null betyder, at API'et ikke returnerede en fejl på rækkeniveau.

Opret en gennemgået opkaldsliste til salg

Når phone_results er tilgængelig, kan du oprette en lokal liste, som salgsteamet kan gennemgå. Tilføj denne blok efter udskrivningen af resultaterne i samme fil. Den genbruger de eksisterende resultater og foretager ikke endnu et API-kald:

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))

Resultatindekset bruger inputId som join key, så hvert resultat forbliver knyttet til sin kildepost uden at afhænge af placeringen i listen. API-payloaden indeholder hver prospects ID og profil-URL, mens den oprindelige prospects-liste bevarer navnet og account owner, som opkaldslisten skal bruge.

For Florians række forbinder prospect-florian-poullin det returnerede resultat med de oprindelige værdier for name, linkedin_url og account_owner. Teamet læser telefonnummeret og landekoden FR fra result.outputs. Hele API-objektet, herunder status, credits og fejl, forbliver vedhæftet under result.

Opkaldslistens loop følger rækkefølgen i prospects. Det kopierer hver medtaget prospect, før result tilføjes, så den oprindelige kildeliste fortsat kan bruges til rettelser eller en anden opfølgningskanal.

En række uden resultat, med fejl eller uden telefonnummer bliver i den uændrede prospects-liste, men føjes ikke til call_list. Koden opretter en lokal opkaldsliste, der er klar til gennemgang.

Beregn prisen på Waterfall Phone Finder API

Hvert nyt telefonnummer, som findes uden cache via den administrerede standard-waterfall, koster 500 credits. Et accepteret cachelagret resultat koster 0 credits, og et opslag uden resultat koster også 0 credits. Se creditsUsed på hver returneret række for at finde det faktiske forbrug i stedet for at gange alle indsendte profiler med 500.

Brug denne formel til budgettering:

nye fundne telefonnumre uden cache × 500 credits

40 nye numre bruger 20.000 credits. 100 nye numre bruger 50.000 credits. Med den aktuelle basispris for optankning i USD giver $20 dig 20.000 credits, så 500 credits svarer til $0,50. Growth-abonnementet, der giver adgang til REST API, afregnes separat. Se Datablists priser for aktuelle abonnementer og credit-pakker.

Antag som budgeteksempel, at 100 profiler giver 20 nye numre, 5 accepterede cachelagrede numre og 75 opslag uden resultat. Den fakturerbare mængde er de 20 nye numre, så opslaget bruger 10.000 credits. Opkaldslisten kan indeholde alle 25 fundne numre. Indtast 20 i beregneren – ikke alle 100 inputs eller alle 25 fundne numre. Eksemplet viser, hvordan prisen beregnes, ikke en forventet succesrate.

Loading pricing…

Løs typiske fejl, og gendan en eksisterende task

  • DATABLIST_API_KEY mangler: Scriptet stopper, før det sender en request. Eksportér variablen, og kør filen igen.
  • API'et afviser din key: raise_for_status() viser HTTP-fejlen. Kopiér din Personal API Key igen, og bekræft, at requesten sender den i headeren X-API-Key.
  • Profil-URL'en understøttes ikke: Erstat en tom eller ugyldig URL, en virksomheds-URL eller en Sales Navigator-URL med en offentlig personprofil, der bruger stien linkedin.com/in/....
  • Der er ikke nok credits: Tjek kontoens saldo og tilgængelige credits, før du indsender flere opslag.
  • Tasken har statussen failed eller stopped: Undersøg fejlen, de tilgængelige resultater og credit-forbruget, før du beslutter, hvad der stadig skal køres.
  • En række har intet resultat eller en fejl: Behold prospecten i kildedataene, så den kan rettes eller bruges i en anden opfølgningskanal. Rækken alene forklarer ikke, hvilken udbyder, geografi eller synlighedsbegrænsning der var årsag til resultatet.

Hvis POST-svaret går tabt, skal du bruge det uniqueId, der blev udskrevet før indsendelsen. Vis dine tasks, før du indsender igen. Erstat your-api-key i denne request, og find derefter den task, hvis uniqueId matcher den udskrevne værdi:

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 tasken ikke er på den første side, skal du følge nextCursor i svaret med task-listen. Kopiér den matchende tasks @id, erstat TASK_ID nedenfor, og tjek dens status, eller hent dens eksisterende resultater:

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"

Dokumentationen til task-API'et forklarer task-statusser, paginering af resultater og håndtering af afbrydelser.

Næste skridt

Du har nu én genanvendelig Requests-funktion til offentlige LinkedIn-profil-URL'er og én sammenfletning via stabile ID'er, der gør fundne telefonnumre klar til salgsteamets gennemgang.

Erstat de redigerbare eksempler med et mindre udvalg af kvalificerede prospects. Behold deres stabile ID'er og account owners, og gennemgå hvert fundet nummer, før du sender den klargjorte liste videre til teamets opkaldsproces. Begynd med en lille batch, så du kan kontrollere ID-mappingen og de returnerede felter. Har du brug for non-blocking concurrency, kan du bruge det vedligeholdte async HTTPX-eksempel.