Du kan hitta telefonnummer från LinkedIn i Python genom att skicka offentliga
profil-URL:er av typen linkedin.com/in/... till Datablists Waterfall Phone Finder API.
API:et kontrollerar tillgängliga leverantörer av telefondata i tur och ordning och returnerar
hittade nummer i internationellt format med landskod.
Den här guiden använder biblioteket Requests för att skapa en komplett integration i Python. Därefter återanvänder vi samma resultat för att ta fram en lokal ringlista som innehåller varje prospects namn, LinkedIn-URL och kontoansvarig.
📌 Snabb sammanfattning
Använd ett enda API för att hitta telefonnummer från en lista med offentliga LinkedIn-profiler. Skapa sedan en lokal ringlista med varje prospects namn och kontoansvarig. Waterfall Phone Finder testar tillgängliga leverantörer i tur och ordning och gör de hittade numren redo för teamets granskning.
- Input: Prospect-poster med en offentlig LinkedIn-profil.
- Output: En lokal ringlista med hittade internationella telefonnummer, landskoder, namn och kontoansvariga.
💡 Föredrar du en no-code-lösning? Använd Datablists Waterfall Phone Finder för att hitta telefonnummer från LinkedIn-profiler utan att skriva kod.
Om du börjar med namn i stället för profil-URL:er kan du först följa vårt no-code-flöde från namn till telefonnummer eller hitta LinkedIn-profiler från namn i Python.
Konfigurera Python, Requests och din Datablist API-nyckel
I det här Python-exemplet använder jag paketet requests. Skapa en projektmapp,
aktivera en virtuell miljö, installera Requests och skapa 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"Skapa en Personal API Key i ditt
Datablist-konto och använd den som DATABLIST_API_KEY. Åtkomst till REST API
är en funktion i Growth-planen. Längre fram i guiden går jag igenom hur många
credits en lyckad sökning använder.
Hitta telefonnummer med en komplett Python-funktion
Exemplet innehåller tre prospect-poster som du kan redigera. Varje post har ett beständigt
prospect_id, ett namn, en offentlig LinkedIn-URL och den kontoansvariga som ska
granska 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/
Endast det beständiga ID:t och LinkedIn-URL:en behöver skickas till API:et. Namnet och den kontoansvariga stannar i din lokala källpost. Uppdelningen håller lookup-requesten liten samtidigt som den affärsinformation teamet behöver finns kvar när resultatet returneras.
Klistra in hela 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))Kör filen med:
python find_phone_numbers.pyDu kan även ladda ned Datablists underhållna synkrona Requests-exempel. Skriptet ovan följer samma enkla ordning: skicka in en task, vänta tills den är klar och hämta samtliga resultatsidor.
Skicka telefonuppslaget
List comprehension-uttrycket omvandlar varje prospect i källdatan till API:ets input-format.
Ditt prospect_id blir inputId, medan linkedin_url blir
data.profileUrl. Använd en offentlig personprofil med sökvägen
linkedin.com/in/.... Sales Navigator-URL:er stöds inte av denna
enrichment.
Funktionen genererar uniqueId och skriver ut det före POST-anropet. Requesten
skickar värdet tillsammans med enrichment-ID:t waterfall-phone-finder, cache-
inställningen och all input. En lyckad inskickning returnerar HTTP 202 Accepted
och ett @id för tasken, medan bearbetningen fortsätter i bakgrunden.
API-dokumentationen för Waterfall Phone Finder listar aktuella inställningar, input-fält, output, credits och begränsningar.
För en prospect har request body följande 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 offentliga profil-URL:en används som input för sökningen. inputId är den join key
som kopplar resultatet till namnet och den kontoansvariga i din källpost. Välj
ett ID som är beständigt i ditt eget system och unikt inom tasken.
Vänta på bakgrundstasken
Requests-klienten blockerar lokalt medan den kontrollerar tasken var tredje
sekund. Datablist-tasken fortsätter samtidigt att köras i bakgrunden. När statusen blir
completed börjar funktionen hämta resultaten. Statusen failed eller stopped
utlöser ett fel med task-ID:t så att du kan undersöka vad som hänt.
Hämta alla resultatsidor
Resultatanropet begär upp till 100 rader åt gången. Det fortsätter att hämta sidor
tills nextCursor är null. Varje resultat innehåller sitt ursprungliga inputId, så att du
kan mappa det till rätt prospect utan att förlita dig på svarens ordning.
Så hittar ett hanterat waterfall-flöde telefonnummer
I exemplet sätts cacheAge till "30". Datablist kontrollerar först om det finns
ett tillgängligt resultat som är högst 30 dagar gammalt. Om ett sådant finns kan API:et
återanvända det. Inställningen tillåter en cache-träff, men garanterar inte att en finns.
Om profilen fortfarande inte har gett något resultat testar det hanterade waterfall-flödet tillgängliga leverantörer av telefondata i tur och ordning. Om en leverantör inte returnerar något användbart nummer går posten vidare. När ett användbart nummer hittas stoppas sekvensen för den posten.
Därför fungerar waterfall bättre i flera länder och marknader
Datablist förlitar sig inte på en enda leverantör av telefondata. Leverantörerna använder olika datamängder, och deras täckning varierar mellan länder och marknader. När en leverantör saknar ett telefonnummer kan en annan hitta det. Datablist hanterar dessa leverantörer via samma API-integration.
För ett säljteam som bygger en ringlista för flera marknader innebär det att färre prospects faller bort när en enskild leverantör inte hittar något. Din Python-kod skickar en task och läser ett enda resultatformat, så du slipper bygga och underhålla en separat integration för varje leverantör.
Sätt cacheAge till "0" när ditt arbetsflöde uttryckligen kräver en helt ny
sökning. Behåll "30" i exemplet så att ett tillgängligt cachelagrat resultat kan återanvändas.
Läs hela resultatet
Här är ett resultat för Florian Poullin. Telefonnumret är maskerat nedan.
{
"inputId": "prospect-florian-poullin",
"status": "success",
"outputs": {
"finderProvider": "wizleads",
"phoneNumber": "+33 • •• •• •• ••",
"phoneNumberCountry": "FR"
},
"creditsUsed": "500",
"error": null
}phoneNumber innehåller det internationella numret när ett sådant är tillgängligt.
Prefixet +33 och phoneNumberCountry: "FR" visar att det är ett franskt nummer.
finderProvider anger vilken finder som rapporterats för resultatet. Raden använde 500
credits, och error: null innebär att API:et inte returnerade något fel på radnivå.
Skapa en granskad ringlista för säljteamet
När phone_results är tillgängligt kan du skapa en lokal lista som säljteamet
kan granska. Lägg till blocket nedan efter utskriften av resultatet i samma fil. Det
återanvänder de befintliga resultaten och gör inget ytterligare API-anrop:
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))Resultatindexet använder inputId som join key, så varje resultat förblir kopplat till sin
källpost utan att vara beroende av listpositionen. API-payloaden innehåller varje
prospects ID och profil-URL, medan den ursprungliga listan prospects behåller namnet
och den kontoansvariga som behövs i ringlistan.
För Florians rad kopplar prospect-florian-poullin det returnerade resultatet till
det ursprungliga name, linkedin_url och account_owner. Teamet hämtar
telefonnumret och landskoden FR från result.outputs. Det fullständiga API-objektet,
inklusive status, credits och eventuella fel, ligger kvar under result.
Loopen för ringlistan följer ordningen i prospects. Den kopierar varje prospect
som ska tas med innan result läggs till. Därmed finns den ursprungliga källistan
kvar för korrigeringar eller en annan uppföljningskanal.
En rad utan resultat, med fel eller utan telefonnummer ligger kvar oförändrad i listan
prospects, men läggs inte till i call_list. Koden skapar en lokal ringlista
som säljteamet kan granska.
Beräkna kostnaden för Waterfall Phone Finder API
Varje nytt, icke-cachelagrat telefonnummer som hittas av det förvalda hanterade waterfall-flödet
kostar 500 credits. Ett godkänt cachelagrat resultat kostar 0 credits, och en sökning
utan resultat kostar också 0 credits. Läs creditsUsed på varje returnerad rad för att se
den faktiska kostnaden, i stället för att multiplicera varje inskickad profil med 500.
Använd följande formel för budgetering:
nya icke-cachelagrade telefonnummer som hittas × 500 credits
Fyrtio nya nummer kostar 20 000 credits. Hundra nya nummer kostar 50 000 credits. Med det nuvarande grundpriset för påfyllning i USD ger 20 dollar 20 000 credits, vilket innebär att 500 credits motsvarar 0,50 dollar. Growth-prenumerationen som ger åtkomst till REST API tillkommer separat. Se Datablists priser för aktuella planer och credit-paket.
Anta som planeringsexempel att 100 profiler ger 20 nya nummer, 5 godkända
cachelagrade nummer och 75 sökningar utan träff. Den debiterbara mängden är de 20 nya numren,
så sökningen använder 10 000 credits. Ringlistan kan innehålla alla 25 hittade nummer.
Ange 20 i kalkylatorn, inte samtliga 100 input-poster eller alla 25 hittade
nummer. Exemplet visar hur debiteringen beräknas, inte en förväntad träffsäkerhet.
Lös vanliga fel och återställ en befintlig task
DATABLIST_API_KEYsaknas: skriptet stoppas innan någon request skickas. Exportera variabeln och kör filen igen.- API:et avvisar nyckeln:
raise_for_status()visar HTTP-felet. Kopiera din Personal API Key igen och kontrollera att requesten skickar den i headernX-API-Key. - Profil-URL:en stöds inte: ersätt en tom, felaktig, företags- eller
Sales Navigator-URL med en offentlig personprofil som använder sökvägen
linkedin.com/in/.... - Du har för få credits: kontrollera kontots saldo och tillgängliga credits innan du skickar in fler sökningar.
- Tasken har status
failedellerstopped: kontrollera felet, tillgängliga resultat och förbrukade credits innan du avgör vad som behöver köras igen. - En rad saknar resultat eller innehåller ett fel: behåll prospect-posten i källdatan för korrigering eller uppföljning via en annan kanal. Raden i sig förklarar inte vilken leverantör, geografi eller synlighetsinställning som orsakade utfallet.
Om POST-svaret går förlorat använder du det uniqueId som skrevs ut före inskickningen.
Lista dina tasks innan du skickar in något igen. Ersätt your-api-key i följande
request och leta sedan upp den task vars uniqueId matchar det utskrivna värdet:
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"Om tasken inte finns på första sidan följer du nextCursor i svaret med task-listan.
Kopiera @id från den matchande tasken, ersätt TASK_ID nedan och kontrollera
statusen eller hämta de befintliga resultaten:
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 för task-API:et förklarar task-statusar, paginering av resultat och vad som händer vid avbrott.
Nästa steg
Nu har du en återanvändbar Requests-funktion för offentliga LinkedIn-profiler och en sammanslagning med beständiga ID:n som förbereder hittade telefonnummer för säljteamets granskning.
Ersätt de redigerbara exemplen med en mindre uppsättning kvalificerade prospects. Behåll deras beständiga ID:n och kontoansvariga, och granska sedan varje hittat nummer innan du skickar den färdiga listan vidare till teamets ringprocess. Börja med en liten batch så att du kan kontrollera ID-mappningen och de returnerade fälten. Om du behöver icke-blockerande parallellism kan du använda det underhållna async HTTPX-exemplet.


