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:
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:
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:
python find_phone_numbers.pyDu 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:
{
"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.
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.
{
"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:
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.
Løs typiske fejl, og gendan en eksisterende task
DATABLIST_API_KEYmangler: 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 headerenX-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
failedellerstopped: 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:
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:
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.


