Skip to content

Latest commit

 

History

3 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

leadsearch

Turn a list of names & e-mails into job titles, workplaces and LinkedIn profiles — with e-mail intelligence and result scoring, not just "the first hit".

tests Python ≥ 3.9 MIT

leadsearch enriches a table of leads by querying a search engine (Google Programmable Search or Bing) restricted to LinkedIn, then parsing and scoring the results to pick the best match for each lead.

Smarter than a first-result grab

  • E-mail intelligence — infers the company from the domain (jane@acme-corp.co.ukAcme Corp), guesses a name from the local part when none is given (jane.doe@…Jane Doe), and flags free, role (info@, sales@) and disposable accounts so they don't pollute results.
  • Candidate scoring — every result in the top-N is scored on fuzzy name similarity, whether the URL is a real personal profile, and whether the result's company agrees with the e-mail's domain. The best-scoring candidate wins, with a confidence value — not just items[0].
  • Robust parsing — handles the common LinkedIn title shapes (Name - Title - Company, Name - Title at Company, snippet-only company).
  • Pluggable providers — Google, Bing, or a MockProvider so the whole pipeline is testable offline. Retries with backoff + a politeness delay.

Install

pip install -e ".[test]"          # add ".[pandas]" for DataFrame support

Usage

from leadsearch import LeadSearch, GoogleProvider

ls = LeadSearch(GoogleProvider(api_key="YOUR_KEY", cx="YOUR_CX"))

leads = ls.enrich([
    ("Jane Doe", "jane.doe@acme.com"),
    ("", "john.smith@globex.io"),      # name recovered from the address
    ("Sales", "sales@acme.com"),       # flagged as a role account
])

for lead in leads:
    print(lead.as_dict())
# {'name': 'Jane Doe', 'title': 'Head of Data', 'workplace': 'Acme',
#  'link': 'https://linkedin.com/in/janedoe', 'confidence': 0.86, ...}

Bing works the same way via BingProvider(api_key="…"). A pandas frame:

enriched = ls.enrich_dataframe(df, name_col="name", email_col="email")

Caching, MX intelligence & bulk (v0.2)

Cache repeated queries so you don't re-bill the API — in memory or persisted:

from leadsearch import LeadSearch, GoogleProvider, CachingProvider, JSONFileCache

provider = CachingProvider(GoogleProvider(api_key="…", cx="…"),
                           JSONFileCache("leadsearch-cache.json"))
ls = LeadSearch(provider)

MX intelligence — a custom domain hosted on Google Workspace / Microsoft 365 is a real company, not free webmail. Pass mx_lookup (needs pip install ".[dns]") to detect the mail host, confirm deliverability, and recover a company name the plain heuristic missed:

from leadsearch.domain_intel import default_mx_lookup
ls = LeadSearch(provider, mx_lookup=default_mx_lookup)
# notes: "mail hosted on microsoft" / "domain has no MX record (may be undeliverable)"

Bulk, concurrently — the search calls are I/O-bound, so a thread pool speeds up large lists (output order preserved):

leads = ls.enrich(rows, workers=8)

Testing offline

from leadsearch import LeadSearch, MockProvider
from leadsearch.types import SearchItem

mock = MockProvider(items=[SearchItem(title="Jane Doe - Head of Data - Acme | LinkedIn",
                                      link="https://linkedin.com/in/janedoe")])
LeadSearch(mock).enrich_one("Jane Doe", "jane@acme.com")

API

Object Purpose
LeadSearch(provider) .enrich(leads), .enrich_one(name, email), .enrich_dataframe(df)
GoogleProvider / BingProvider / MockProvider Search backends
analyze_email(email) Company / name / account-type inference
parse_linkedin(title, snippet, name) Parse a result into name/title/company
score_candidate / rank_candidates Result scoring
Lead Enriched result dataclass

Getting API keys

Google Programmable Search (an API key + a search-engine cx) or the Bing Web Search API.

R version

The original R implementation lives at HenrikVarmer/LeadSearch-R.

License

MIT © Henrik Varmer

About

Enrich (name, email) leads with job title, workplace and LinkedIn via search APIs (Python).

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages