Você pode extrair dados de perfis do LinkedIn com Python enviando URLs públicas conhecidas para a LinkedIn Profile Scraper API da Datablist por meio da biblioteca Requests. A API retorna campos estruturados de identidade, localização, histórico profissional, formação acadêmica e empresa para criar listas de leads e personalizar o outreach com informações relevantes sobre cargo e empresa.
Este guia usa a URL do perfil público de Satya Nadella como um exemplo compacto. Você executará uma tarefa completa de extração de perfil, interpretará o cargo na Microsoft e as experiências profissionais com datas e, depois, manterá o resultado junto ao lead de origem antes de preparar o outreach.
🔑 Resumo para quem está com pressa: Envie à Datablist URLs conhecidas de perfis pessoais do LinkedIn e obtenha dados disponíveis de perfil, localização, histórico profissional, formação acadêmica e empresa em JSON estruturado. O exemplo em Python abaixo mantém essas informações junto a cada lead de origem, permitindo qualificar a lista e preparar um outreach mais relevante.
- Input: URLs conhecidas de perfis pessoais do LinkedIn.
- Output: Dados estruturados do perfil armazenados com cada contato de origem.
💡 Prefere uma solução no-code? Use o LinkedIn Profile Scraper da Datablist para extrair dados de URLs de perfis conhecidos sem escrever código.
Configure a API da Datablist e o ambiente Python
O acesso à REST API da Datablist está incluído no plano Growth. A consulta de perfis também consome créditos de enrichment, detalhados na seção de custos.
Crie uma Personal API Key na página da sua conta da API Datablist. Este exemplo mostra o formato da Personal API Key:
exampleuser-exampleaccount-EXAMPLE_TOKEN_NOT_VALID-2🔑 Já tem uma API key? As chaves antigas usam
auth0|<userId>:<accountId>:<secret>:1e continuam sendo aceitas. Continue usando sua chave atual exatamente como ela foi gerada; não é necessário substituí-la nem alterar seu formato.
O script lê sua chave na variável de ambiente DATABLIST_API_KEY e a envia no header X-API-Key.
Neste exemplo em Python, uso o pacote requests. Os comandos de configuração abaixo são para um shell do macOS ou Linux. Crie uma pasta para o projeto, abra-a no terminal e execute:
python -m venv .venv
source .venv/bin/activate
python -m pip install requestsEm seguida, crie um arquivo chamado scrape_linkedin_profiles.py e exporte sua chave:
export DATABLIST_API_KEY="your-personal-api-key"Extraia um perfil do LinkedIn completo com Python
O registro de origem deste passo a passo contém um ID de contato estável e uma URL de perfil conhecida:
{
"contact_id": "contact-satya-nadella",
"profile_url": "https://www.linkedin.com/in/satyanadella/"
}O script envia contact_id como inputId da API. Os resultados não precisam chegar na mesma ordem dos inputs; por isso, esse ID oferece uma forma confiável de associar cada resultado ao contato de origem.
Cole o script completo abaixo em scrape_linkedin_profiles.py:
import json
import os
import time
import uuid
import requests
def scrape_profiles(source_contacts, api_key):
"""Submit one task, wait for completion, and return every result page."""
tasks_url = "https://api.datablist.com/v1/enrichments/tasks"
headers = {"X-API-Key": api_key}
inputs = [
{
"inputId": contact["contact_id"],
"data": {"profileUrl": contact["profile_url"]},
}
for contact in source_contacts
]
unique_id = str(uuid.uuid4())
print(f"Task uniqueId: {unique_id}", flush=True)
payload = {
"enrichmentId": "linkedin-profile-scraper",
"uniqueId": unique_id,
"settings": {
"experiencesNb": "5",
"educationsNb": "3",
"acceptCachedProfiles": False,
"includeUrn": False,
"includePictures": False,
},
"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}"
print(f"Task ID: {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 RuntimeError("Set DATABLIST_API_KEY before running this script.")
source_contacts = [
{
"contact_id": "contact-satya-nadella",
"profile_url": "https://www.linkedin.com/in/satyanadella/",
}
]
profile_results = scrape_profiles(source_contacts, api_key)
print(json.dumps(profile_results, indent=2))Execute com:
python scrape_linkedin_profiles.pyAs configurações solicitam cinco experiências profissionais e três registros de formação acadêmica. A API espera que essas quantidades sejam enviadas como strings. acceptCachedProfiles: false solicita uma consulta atualizada, enquanto as opções de imagem e ID interno permanecem desativadas porque este workflow utiliza campos duráveis de texto e URL.
Use uma URL pública padrão de perfil /in/ ou uma URL de lead do Sales Navigator para cada input. O nome de uma pessoa, uma página de pesquisa do LinkedIn e uma página de empresa representam tarefas diferentes e não são inputs de perfil válidos para este scraper. Se a fonte contiver links do Sales Navigator, o profileUrl retornado poderá ser a URL pública normalizada do perfil. Para listas maiores, mantenha cada inputId único e estável, em vez de derivá-lo da posição da linha.
As quantidades de histórico controlam quantos campos simples e numerados de experiências e formação acadêmica a API pode retornar. Elas não alteram o custo em créditos por perfil. Solicite histórico suficiente para sua análise, mas evite selecionar dez experiências se pretende verificar apenas os cargos mais recentes.
O que fazem as três chamadas à API
A requisição POST envia as configurações selecionadas e os inputs de perfil. A Datablist aceita o trabalho como uma tarefa em segundo plano e retorna seu @id. O script exibe tanto o uniqueId gerado quanto o ID retornado da tarefa, fornecendo os valores necessários para consultá-la posteriormente.
A primeira chamada GET verifica o status da tarefa a cada três segundos. O client Python fica bloqueado durante a espera, mas a tarefa da API continua sendo executada em segundo plano. O loop termina quando o status é completed, failed ou stopped.
A segunda chamada GET recupera os resultados em páginas de até 100 registros. Quando nextCursor contém um valor, o script busca a página seguinte. Ele termina quando nextCursor é null.
Analise o resultado e escolha as configurações
A URL enviada determina qual perfil será extraído. A Datablist aceita URLs públicas de perfis pessoais e URLs de leads do Sales Navigator, normaliza a URL do perfil quando necessário e mapeia os dados públicos disponíveis em campos simples de perfil, experiência profissional, formação acadêmica e empresa.
A consulta atualizada usada neste guia foi concluída com sucesso e consumiu 25 créditos. Veja o resultado completo:
{
"inputId": "contact-satya-nadella",
"status": "success",
"outputs": {
"profileUrl": "https://www.linkedin.com/in/satyanadella/",
"fullName": "Satya Nadella",
"firstName": "Satya",
"lastName": "Nadella",
"linkedInHeadline": "Chairman and CEO at Microsoft",
"linkedInSummary": "As chairman and CEO of Microsoft, I define my mission and that of my company as empowering every person and every organization on the planet to achieve more.",
"linkedInProfilePicture": "https://media.licdn.com/dms/image/v2/C5603AQHHUuOSlRVA1w/profile-displayphoto-shrink_800_800/profile-displayphoto-shrink_800_800/0/1579726625483?e=1794441600&v=beta&t=I1sL---bTuvjxqb1vdbNsNy-fAsLCpBj3-WtJjOGbOc",
"linkedInInternalIdentifier": "ACoAAAEkwwAB9KEc2TrQgOLEQ-vzRyZeCDyc6DQ",
"linkedInLocation": "Redmond, Washington, United States",
"linkedInCity": "Redmond",
"linkedInState": "Washington",
"linkedInCountryName": "United States",
"linkedInCountryCode": "US",
"linkedInLanguages": "",
"linkedInConnections": 832,
"linkedInlastExpTitle": "Chairman and CEO",
"linkedInlastExpCompany": "Microsoft",
"linkedInlastExpEmploymentType": null,
"linkedInlastExpLocation": "Greater Seattle Area",
"linkedInlastExpStartsAt": "2014-02-01",
"linkedInlastExpEndsAt": null,
"linkedInlastExpDescription": null,
"linkedInlastExpCompanyWebsite": "https://news.microsoft.com/",
"linkedInlastExpCompanyPage": "https://www.linkedin.com/company/microsoft/",
"linkedInlastExpCompanyIndustry": "Software Development",
"linkedInlastExpCompanyRange": "10001+",
"linkedInlastExpCompanyDescription": "Every company has a mission. What's ours? To empower every person and every organization to achieve more. We believe technology can and should be a force for good and that meaningful innovation contributes to a brighter world in the future and today. Our culture doesn’t just encourage curiosity; it embraces it. Each day we make progress together by showing up as our authentic selves. We show up with a learn-it-all mentality. We show up cheering on others, knowing their success doesn't diminish our own. We show up every day open to learning our own biases, changing our behavior, and inviting in differences. Because impact matters. \n\nMicrosoft operates in 190 countries and is made up of approximately 228,000 passionate employees worldwide.",
"linkedInlastExpCompanyLogo": "https://media.licdn.com/dms/image/v2/D560BAQH32RJQCl3dDQ/company-logo_200_200/B56ZYQ0mrGGoAM-/0/1744038948046/microsoft_logo?e=1793836800&v=beta&t=4wXD40LQU4IfLY4DiEvT2bwvjUoPQPGgi5_T-vPsbQ8",
"linkedIn2ExpTitle": "Chairman",
"linkedIn2ExpCompanyName": "The Business Council U.S.",
"linkedIn2ExpEmploymentType": null,
"linkedIn2ExpStartsAt": "2021-01-01",
"linkedIn2ExpEndsAt": "2023-01-01",
"linkedIn2ExpDescription": null,
"linkedIn2ExpLogo": "https://media.licdn.com/dms/image/v2/C4D0BAQGcnaZNpjMvrw/company-logo_200_200/company-logo_200_200/0/1630557702704/the_business_council_us_logo?e=1793836800&v=beta&t=Ejb0D8lV5sMTFwcz_-FKdfQvIvq-mKx_Nl8vRMib53k",
"linkedIn3ExpTitle": "Member Board Of Trustees",
"linkedIn3ExpCompanyName": "University of Chicago",
"linkedIn3ExpEmploymentType": null,
"linkedIn3ExpStartsAt": "2018-01-01",
"linkedIn3ExpEndsAt": null,
"linkedIn3ExpDescription": null,
"linkedIn3ExpLogo": "https://media.licdn.com/dms/image/v2/D4E0BAQGDP-PXY3u8dw/company-logo_200_200/B4EaENqZTQGoAM-/0/1791230580227/uchicago_logo?e=1793836800&v=beta&t=NJGoETr0tY868Z2pvlyXeh939iXwW0WbSFwRctabEVU",
"linkedIn4ExpTitle": "Board Member",
"linkedIn4ExpCompanyName": "Starbucks",
"linkedIn4ExpEmploymentType": null,
"linkedIn4ExpStartsAt": "2017-01-01",
"linkedIn4ExpEndsAt": "2024-01-01",
"linkedIn4ExpDescription": null,
"linkedIn4ExpLogo": "https://media.licdn.com/dms/image/v2/C4D0BAQEQxk9y2rk7Hw/company-logo_200_200/company-logo_200_200/0/1631316692275?e=1793836800&v=beta&t=NVjljhe0oI5KzvJHodAJjss5EdvxaOIzQQ2rAGyh_AQ",
"linkedIn5ExpTitle": "Board Member",
"linkedIn5ExpCompanyName": "Fred Hutch",
"linkedIn5ExpEmploymentType": null,
"linkedIn5ExpStartsAt": "2016-01-01",
"linkedIn5ExpEndsAt": "2022-01-01",
"linkedIn5ExpDescription": null,
"linkedIn5ExpLogo": "https://media.licdn.com/dms/image/v2/D4D0BAQGF4eOou62nvQ/company-logo_200_200/company-logo_200_200/0/1664795263764/fredhutch_logo?e=1793836800&v=beta&t=dJWSO-KkuBPd6I6aRYBoIcQVzcSEmGLwqYy-VMFXJQc",
"linkedInlastEduSchool": "The University of Chicago Booth School of Business",
"linkedInlastEduDegree": null,
"linkedInlastEduField": null,
"linkedInlastEduStartsAt": "1994-01-01",
"linkedInlastEduEndsAt": "1996-01-01",
"linkedInlastEduPage": "https://www.linkedin.com/school/universityofchicagoboothschoolofbusiness/",
"linkedInlastEduLogo": "https://media.licdn.com/dms/image/v2/D560BAQFZO05jhYKSkw/company-logo_200_200/company-logo_200_200/0/1692627816910/universityofchicagoboothschoolofbusiness_logo?e=2147483647&v=beta&t=BTjFA4UVU5iKIIyicg8d44rhoiuMbetNDB97BmqpwhQ",
"linkedIn2EduSchool": "Manipal Institute of Technology",
"linkedIn2EduDegree": "Bachelor’s Degree",
"linkedIn2EduField": "Electrical Engineering",
"linkedIn2EduStartsAt": null,
"linkedIn2EduEndsAt": null,
"linkedIn2EduPage": "https://www.linkedin.com/school/manipal-institute-of-technology/",
"linkedIn2EduLogo": "https://media.licdn.com/dms/image/v2/D4D0BAQHodG_7cUqs6w/company-logo_200_200/B4DZ8hC8AUJQAE-/0/1782965846314/manipal_institute_of_technology_logo?e=2147483647&v=beta&t=jqJK15_r7lxUNgWdbbzdMq47aLa_PqnkDYxg4Jun4Zo",
"linkedIn3EduSchool": "University of Wisconsin-Milwaukee",
"linkedIn3EduDegree": "Master’s Degree",
"linkedIn3EduField": "Computer Science",
"linkedIn3EduStartsAt": null,
"linkedIn3EduEndsAt": null,
"linkedIn3EduPage": "https://www.linkedin.com/school/uwmilwaukee/",
"linkedIn3EduLogo": "https://media.licdn.com/dms/image/v2/D4D0BAQE47QlO_LG8SQ/company-logo_200_200/company-logo_200_200/0/1729615751602/uwmilwaukee_logo?e=2147483647&v=beta&t=l-w3ttd1mZRc-_j5aCPXEzNiYJzl1iJjMGw7q8B3eRI"
},
"creditsUsed": "25",
"error": null
}Analise o cargo, a empresa, a data de início e a data de término em conjunto. O registro da Microsoft começa em fevereiro de 2014 e não tem data de término. O registro do The Business Council U.S. vai de 2021 a janeiro de 2023. Essas datas diferenciam uma experiência em andamento de outra já encerrada e também mostram como os cargos podem se sobrepor.
linkedInlastExpTitle e linkedInlastExpCompany contêm a experiência atual ou a última experiência mapeada. Esse primeiro registro pode incluir dados mais completos da empresa, como página corporativa, site, setor, descrição e faixa de funcionários. Os registros numerados acrescentam cargos, empresas e datas anteriores. Nesta resposta, o site retornado para a Microsoft é https://news.microsoft.com/. Essa URL acrescenta ao registro do lead uma fonte útil sobre a empresa, além do histórico profissional da pessoa.
Os campos linkedInlastEduSchool, linkedIn2EduSchool e linkedIn3EduSchool identificam The University of Chicago Booth School of Business, Manipal Institute of Technology e University of Wisconsin-Milwaukee. O registro de Manipal inclui um bacharelado em Engenharia Elétrica, enquanto o de Wisconsin-Milwaukee inclui um mestrado em Ciência da Computação. Os valores de diploma e área de estudo de Chicago estão vazios.
Use os valores "3", "5" ou "10" em experiencesNb e "1", "3" ou "5" em educationsNb para escolher quanto histórico deseja obter. Leia esses campos diretamente de outputs quando forem relevantes para sua pesquisa. Um valor opcional vazio não significa que o resultado inteiro falhou.
O modo fresh é adequado para preparar listas de leads quando você deseja uma nova consulta dos dados públicos disponíveis no perfil. O modo cached pode retornar um perfil armazenado por menos créditos e recorrer a uma nova consulta quando não houver um perfil em cache. Escolha de acordo com a atualidade desejada e seu orçamento de créditos.
Prepare registros de leads para o outreach
Quando profile_results estiver disponível, você poderá anexar cada resposta ao respectivo contato de origem sem enviar outra tarefa. O bloco abaixo reutiliza as variáveis criadas pelo script completo:
results_by_input_id = {
result["inputId"]: result
for result in profile_results
}
contact_research = []
for contact in source_contacts:
result = results_by_input_id[contact["contact_id"]]
contact_research.append(
{
"contact_id": contact["contact_id"],
"source_profile_url": contact["profile_url"],
"result_status": result["status"],
"profile": result.get("outputs", {}),
"credits_used": result["creditsUsed"],
"error": result.get("error"),
}
)
research_record = contact_research[0]
profile = research_record["profile"]
print("Contact:", profile.get("fullName"))
print("Headline:", profile.get("linkedInHeadline"))
print("Location:", profile.get("linkedInLocation"))
print(
"First work entry:",
profile.get("linkedInlastExpTitle"),
"at",
profile.get("linkedInlastExpCompany"),
)O dicionário indexado por inputId lida com respostas fora de ordem. contact-satya-nadella permanece tanto como ID de origem quanto como ID da API, a URL conhecida do LinkedIn continua em source_profile_url e profile preserva o objeto outputs original sem alterações.
Esse wrapper mantém o perfil completo retornado junto à URL de origem, ao status da API e ao consumo de créditos. Você pode usar o headline, a localização e a primeira experiência exibidos para qualificar o lead e acrescentar ao outreach um contexto relevante sobre cargo ou empresa. As linhas da API sem sucesso preservam o status e o erro retornados, mantendo-se visíveis na lista de leads.
Você pode baixar o exemplo de Requests com execução bloqueante ou usar a alternativa assíncrona com HTTPX depois de compreender o fluxo bloqueante.
Calcule o custo da extração de perfis do LinkedIn
Uma consulta fresh consome 25 créditos por perfil. Quando os perfis em cache estão habilitados, um resultado disponível em cache consome 20 créditos; se não houver resultado em cache, a API ainda pode recorrer a uma consulta fresh de 25 créditos. O exemplo fresh de Satya Nadella consumiu 25 créditos.
Para 1.000 perfis, a consulta consome 20.000 créditos se todos os perfis solicitados estiverem disponíveis em cache ou até 25.000 créditos no modo fresh. O acesso à REST API da Datablist exige o plano Growth. A assinatura, os créditos incluídos e os pacotes adicionais de créditos são componentes separados do custo. Consulte a página de preços para ver os valores atuais.
Usando como referência o pacote adicional atual de US$ 20 por 20.000 créditos, o valor estimado dos créditos consumidos é de US$ 20 para consultar 1.000 perfis totalmente em cache ou de US$ 25 para uma consulta fresh. Essas estimativas não incluem o custo da assinatura Growth.
Corrija erros comuns e recupere uma tarefa
DATABLIST_API_KEYnão foi definida: o script é interrompido antes de fazer uma requisição. Exporte a variável e execute o arquivo novamente.- A API rejeita a chave: confira a Personal API Key e envie apenas a credencial
X-API-Keyusada neste exemplo. - A URL do perfil está ausente ou malformada: use uma URL pública de perfil pessoal do LinkedIn ou uma URL compatível de lead do Sales Navigator. O nome de uma pessoa, uma página de pesquisa ou uma página de empresa não serve como input de perfil.
- Os créditos são insuficientes: verifique seu saldo e use os créditos incluídos ou adquira um pacote adicional antes de criar outra tarefa.
- A tarefa está como
failedoustopped: verifique o erro, os resultados disponíveis e o consumo de créditos antes de decidir se é necessário fazer outro envio pago. - Um resultado tem poucos dados, está como
no_resultouerror: verifique o status e o erro público e, depois, confirme a URL e as configurações. Os campos disponíveis podem variar conforme o perfil, sua visibilidade e a consulta.
Se a conexão cair durante o POST, use o uniqueId exibido antes do envio. Liste as tarefas recentes do scraper e compare os valores antes de criar outra tarefa:
response = requests.get(
"https://api.datablist.com/v1/enrichments/tasks",
headers={"X-API-Key": api_key},
params={"enrichmentId": "linkedin-profile-scraper", "limit": 100},
)
response.raise_for_status()
printed_unique_id = "paste-the-printed-unique-id"
tasks = response.json()["tasks"]
matching_task = None
for task in tasks:
if task["uniqueId"] == printed_unique_id:
matching_task = task
break
if matching_task:
print("Task ID:", matching_task["@id"])A lista de tarefas pode ser filtrada por enrichmentId, mas não por uniqueId. Siga o nextCursor se a tarefa não estiver na primeira página. Depois de obter o ID da tarefa, continue usando as mesmas URLs de status e resultados utilizadas pela função principal. A documentação da task API explica com mais detalhes o ciclo de vida, a paginação e o comportamento em caso de interrupção.
Próximos passos
Agora você tem uma função reutilizável com Python Requests que transforma URLs conhecidas de perfis do LinkedIn em resultados estruturados, além de registros de leads associados por um ID estável. Substitua o exemplo por um pequeno conjunto revisado de URLs, escolha entre uma consulta fresh ou cached conforme a atualidade e o custo em créditos desejados e use o contexto retornado de cargo e empresa para qualificar leads ou personalizar o outreach.
Se seus inputs forem URLs de páginas de empresas, consulte o guia em Python para extrair dados de empresas do LinkedIn.
Se você ainda precisa encontrar URLs de perfis a partir de nomes e de uma palavra-chave relacionada a uma empresa ou instituição de ensino, siga o guia separado para encontrar perfis do LinkedIn com Python e uma API antes de executar este scraper.


