Documentation
¶
Index ¶
- Constants
- Variables
- func CompanyURL(slug string) string
- func DefaultDataDir() string
- func DocFromBytes(body []byte) (*goquery.Document, error)
- func JobURL(id string) string
- func LoadCookies(path string) ([]*http.Cookie, error)
- func NormalizeCompanySlug(in string) string
- func NormalizeJobID(in string) string
- func NormalizeProfileSlug(in string) string
- func ProfileURL(slug string) string
- func SchoolURL(slug string) string
- type Affiliation
- type Article
- type Cache
- type Client
- func (c *Client) CachingFetch(ctx context.Context, cache *Cache, cfg Config, url string) ([]byte, error)
- func (c *Client) CachingFetchHTML(ctx context.Context, cache *Cache, cfg Config, url string) (*goquery.Document, error)
- func (c *Client) Fetch(ctx context.Context, rawurl string) ([]byte, int, error)
- func (c *Client) FetchCompany(ctx context.Context, cache *Cache, cfg Config, in string) (*Company, error)
- func (c *Client) FetchCompanyAffiliated(ctx context.Context, cache *Cache, cfg Config, in string) ([]OrgRef, error)
- func (c *Client) FetchCompanyLocations(ctx context.Context, cache *Cache, cfg Config, in string) ([]Location, error)
- func (c *Client) FetchCompanyPosts(ctx context.Context, cache *Cache, cfg Config, in string) ([]Post, error)
- func (c *Client) FetchHTML(ctx context.Context, rawurl string) (*goquery.Document, int, error)
- func (c *Client) FetchJob(ctx context.Context, cache *Cache, cfg Config, id string) (*Job, error)
- func (c *Client) FetchPost(ctx context.Context, cache *Cache, cfg Config, in string) (*Post, error)
- func (c *Client) FetchProfile(ctx context.Context, cache *Cache, cfg Config, in string) (*Profile, error)
- func (c *Client) FetchProfileArticles(ctx context.Context, cache *Cache, cfg Config, in string) ([]Article, error)
- func (c *Client) FetchProfilePosts(ctx context.Context, cache *Cache, cfg Config, in string) ([]Post, error)
- func (c *Client) SearchJobs(ctx context.Context, cache *Cache, cfg Config, opts JobSearchOptions, ...) ([]JobStub, error)
- type Company
- type Config
- type Job
- type JobSearchOptions
- type JobStub
- type Location
- type OrgRef
- type Post
- type Profile
- type Ref
- type Store
- func (s *Store) Close() error
- func (s *Store) CountsByKind() (map[string]int, error)
- func (s *Store) Each(kind string, fn func(id string, data []byte) error) error
- func (s *Store) Get(kind, id string) ([]byte, error)
- func (s *Store) Info() (string, error)
- func (s *Store) Put(kind, id, url string, record any) error
Constants ¶
const ( BaseURL = "https://www.linkedin.com" // GuestJobsSearch is the anonymous job-search endpoint. It returns a list of // server-rendered <li> job cards and accepts the same query parameters the // public jobs page puts on the wire (keywords, location, start, filters). GuestJobsSearch = BaseURL + "/jobs-guest/jobs/api/seeMoreJobPostings/search" // GuestJobDetail serves one job posting as a clean HTML fragment. GuestJobDetail = BaseURL + "/jobs-guest/jobs/api/jobPosting/" DefaultDelay = 2 * time.Second DefaultWorkers = 2 DefaultTimeout = 30 * time.Second DefaultRetries = 3 DefaultCacheTTL = 24 * time.Hour )
Site constants.
const ( KindProfile = "profile" KindCompany = "company" KindSchool = "school" KindJob = "job" KindPost = "post" KindUnknown = "unknown" )
Kinds of LinkedIn entities the tool understands.
Variables ¶
var ErrBlocked = errors.New("blocked: LinkedIn refused the page (sign-in wall or bot block)")
ErrBlocked signals that LinkedIn refused the page: an HTTP 999 bot status, a redirect to the sign-in/authwall, or a body that holds no public data where a JSON-LD graph was expected. Callers map it to the "blocked" exit code.
var ErrNotFound = errors.New("not found")
ErrNotFound signals a 404. Callers map it to the no-data exit code.
var ErrRateLimited = errors.New("rate limited (HTTP 429)")
ErrRateLimited signals a sustained HTTP 429 after retries.
Functions ¶
func DefaultDataDir ¶
func DefaultDataDir() string
DefaultDataDir resolves $XDG_DATA_HOME/linkedin (or ~/.local/share/linkedin).
func DocFromBytes ¶
DocFromBytes parses raw HTML bytes into a goquery document.
func LoadCookies ¶
LoadCookies reads a Netscape/Mozilla cookies.txt file (the format exported by most browser extensions and by curl) into http.Cookie values.
func NormalizeCompanySlug ¶
NormalizeCompanySlug accepts a slug, a /company/<slug> path, or a full URL and returns the bare slug.
func NormalizeJobID ¶
NormalizeJobID accepts a numeric id, a urn:li:jobPosting URN, or a /jobs/view/... URL and returns the bare numeric id.
func NormalizeProfileSlug ¶
NormalizeProfileSlug accepts a slug, an /in/<slug> path, or a full URL and returns the bare slug.
Types ¶
type Affiliation ¶
type Affiliation struct {
Name string `json:"name"`
URL string `json:"url"`
Slug string `json:"slug"`
StartDate int `json:"start_date"`
EndDate int `json:"end_date"`
}
Affiliation is a company or school a person works for or studied at, with the role's year range when LinkedIn exposes it.
type Article ¶
type Article struct {
URL string `json:"url"`
Title string `json:"title"`
Author string `json:"author"`
AuthorURL string `json:"author_url"`
Published string `json:"published"`
Modified string `json:"modified"`
Reactions int64 `json:"reactions"`
Comments int64 `json:"comments"`
ImageURL string `json:"image_url"`
FetchedAt time.Time `json:"fetched_at"`
}
Article is a long-form post a member published, parsed from the Article nodes LinkedIn carries in a profile page's JSON-LD graph.
type Cache ¶
type Cache struct {
// contains filtered or unexported fields
}
Cache is a content-addressed, gzipped on-disk page cache. A captured page is stored under cache/<ab>/<sha256>.html.gz, keyed by its URL.
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
Client performs polite, retrying HTTP GETs against linkedin.com.
func NewClientWithCookies ¶
NewClientWithCookies builds a client pre-loaded with a lent session.
func (*Client) CachingFetch ¶
func (c *Client) CachingFetch(ctx context.Context, cache *Cache, cfg Config, url string) ([]byte, error)
CachingFetch returns page bytes, reading the cache unless NoCache/Refresh is set, and populating it on a miss.
func (*Client) CachingFetchHTML ¶
func (c *Client) CachingFetchHTML(ctx context.Context, cache *Cache, cfg Config, url string) (*goquery.Document, error)
CachingFetchHTML is CachingFetch plus goquery parsing.
func (*Client) Fetch ¶
Fetch returns the raw body and status for a URL, retrying transient failures. A 404 returns (nil, 404, nil). A sign-in redirect or HTTP 999 returns ErrBlocked.
func (*Client) FetchCompany ¶
func (c *Client) FetchCompany(ctx context.Context, cache *Cache, cfg Config, in string) (*Company, error)
FetchCompany fetches and parses a public company page.
func (*Client) FetchCompanyAffiliated ¶
func (c *Client) FetchCompanyAffiliated(ctx context.Context, cache *Cache, cfg Config, in string) ([]OrgRef, error)
FetchCompanyAffiliated returns the related pages (affiliated and showcase) a company links to from its page.
func (*Client) FetchCompanyLocations ¶
func (c *Client) FetchCompanyLocations(ctx context.Context, cache *Cache, cfg Config, in string) ([]Location, error)
FetchCompanyLocations returns the offices a company lists on its page.
func (*Client) FetchCompanyPosts ¶
func (c *Client) FetchCompanyPosts(ctx context.Context, cache *Cache, cfg Config, in string) ([]Post, error)
FetchCompanyPosts returns the recent company posts carried as DiscussionForumPosting nodes in the company page's JSON-LD graph.
func (*Client) FetchProfile ¶
func (c *Client) FetchProfile(ctx context.Context, cache *Cache, cfg Config, in string) (*Profile, error)
FetchProfile fetches and parses a public member profile. The input may be a slug, an /in/<slug> path, or a full URL.
func (*Client) FetchProfileArticles ¶
func (c *Client) FetchProfileArticles(ctx context.Context, cache *Cache, cfg Config, in string) ([]Article, error)
FetchProfileArticles returns the long-form articles carried as Article nodes in a member profile page's JSON-LD graph.
func (*Client) FetchProfilePosts ¶
func (c *Client) FetchProfilePosts(ctx context.Context, cache *Cache, cfg Config, in string) ([]Post, error)
FetchProfilePosts returns the recent posts carried as DiscussionForumPosting nodes in a member profile page's JSON-LD graph.
func (*Client) SearchJobs ¶
func (c *Client) SearchJobs(ctx context.Context, cache *Cache, cfg Config, opts JobSearchOptions, limit int) ([]JobStub, error)
SearchJobs walks the guest search endpoint, page by page, until it has limit stubs or the endpoint returns an empty page. A limit of 0 means "one page".
type Company ¶
type Company struct {
Slug string `json:"slug"`
URL string `json:"url"`
Name string `json:"name"`
Description string `json:"description"`
Slogan string `json:"slogan"`
Website string `json:"website"`
Followers int64 `json:"followers"`
Employees int64 `json:"employees"`
Industry string `json:"industry"`
CompanySize string `json:"company_size"`
CompanyType string `json:"company_type"`
Founded string `json:"founded"`
Specialties string `json:"specialties"`
Headquarters string `json:"headquarters"`
Street string `json:"street"`
Locality string `json:"locality"`
Region string `json:"region"`
PostalCode string `json:"postal_code"`
Country string `json:"country"`
LogoURL string `json:"logo_url"`
FundingRounds int `json:"funding_rounds"`
FundingURL string `json:"funding_url"`
FetchedAt time.Time `json:"fetched_at"`
}
Company is a public company page. The core fields come from the Organization JSON-LD; the about-section fields (followers, industry, size band, type, headquarters, founded, specialties) come from the page's about panel, which carries detail the JSON-LD omits.
type Config ¶
type Config struct {
DataDir string // root for cache/store; defaults to XDG data dir
Workers int // concurrency for multi-page/bulk work
Delay time.Duration // minimum spacing between requests
Timeout time.Duration // per-request timeout
Retries int // retry attempts on 429/5xx
CacheTTL time.Duration // on-disk page-cache freshness window
NoCache bool // bypass the on-disk page cache entirely
Refresh bool // force re-fetch and overwrite the cache
CookiePath string // optional Netscape cookie jar for lent sessions
}
Config holds runtime configuration for the library.
func DefaultConfig ¶
func DefaultConfig() Config
DefaultConfig returns sensible, polite defaults rooted at the XDG data dir.
type Job ¶
type Job struct {
JobID string `json:"job_id"`
URL string `json:"url"`
Title string `json:"title"`
Company string `json:"company"`
CompanyURL string `json:"company_url"`
CompanySlug string `json:"company_slug"`
CompanyLogo string `json:"company_logo"`
Location string `json:"location"`
Posted string `json:"posted"`
Applicants int `json:"applicants"`
Seniority string `json:"seniority"`
EmploymentType string `json:"employment_type"`
JobFunction string `json:"job_function"`
Industries string `json:"industries"`
Description string `json:"description"`
FetchedAt time.Time `json:"fetched_at"`
}
Job is a single job posting, parsed from the guest job-detail fragment.
type JobSearchOptions ¶
type JobSearchOptions struct {
Keywords string
Location string
GeoID string
Posted string // f_TPR, e.g. r86400 (24h), r604800 (week), r2592000 (month)
Remote string // f_WT: 1 on-site, 2 remote, 3 hybrid
Experience string // f_E: 1..6
JobType string // f_JT: F,P,C,T,I,V,O
Sort string // sortBy: R relevance, DD date
}
JobSearchOptions carries the query for the guest job-search endpoint. Every field maps to a parameter the public jobs page puts on the wire (spec §4.1).
type JobStub ¶
type JobStub struct {
JobID string `json:"job_id"`
URL string `json:"url"`
Title string `json:"title"`
Company string `json:"company"`
CompanyURL string `json:"company_url"`
CompanySlug string `json:"company_slug"`
CompanyLogo string `json:"company_logo"`
Location string `json:"location"`
Posted string `json:"posted"`
Benefits string `json:"benefits"`
FetchedAt time.Time `json:"fetched_at"`
}
JobStub is one job card from the guest search endpoint: enough to list and to fetch the full Job.
type Location ¶
type Location struct {
Slug string `json:"slug"`
Primary bool `json:"primary"`
Street string `json:"street"`
Address string `json:"address"`
URL string `json:"url"`
FetchedAt time.Time `json:"fetched_at"`
}
Location is one office a company lists on its page. The full set is read with `company --locations`; the primary office is the registered headquarters.
type OrgRef ¶
type OrgRef struct {
Slug string `json:"slug"`
Name string `json:"name"`
URL string `json:"url"`
Industry string `json:"industry"`
Location string `json:"location"`
FetchedAt time.Time `json:"fetched_at"`
}
OrgRef is a related page a company links to (an affiliated page or showcase), read with `company --affiliated`.
type Post ¶
type Post struct {
URL string `json:"url"`
Author string `json:"author"`
AuthorURL string `json:"author_url"`
Title string `json:"title"`
Text string `json:"text"`
Published string `json:"published"`
Modified string `json:"modified"`
Likes int64 `json:"likes"`
Comments int64 `json:"comments"`
ImageURL string `json:"image_url"`
FetchedAt time.Time `json:"fetched_at"`
}
Post is a best-effort public post or article, parsed from Open Graph tags and any Article/DiscussionForumPosting JSON-LD that serves anonymously.
type Profile ¶
type Profile struct {
Slug string `json:"slug"`
URL string `json:"url"`
Name string `json:"name"`
Headline string `json:"headline"`
Description string `json:"description"`
JobTitles []string `json:"job_titles"`
Location string `json:"location"`
Country string `json:"country"`
Followers int64 `json:"followers"`
ImageURL string `json:"image_url"`
Languages []string `json:"languages"`
Awards []string `json:"awards"`
WorksFor []Affiliation `json:"works_for"`
AlumniOf []Affiliation `json:"alumni_of"`
MemberOf []Affiliation `json:"member_of"`
SameAs []string `json:"same_as"`
FetchedAt time.Time `json:"fetched_at"`
}
Profile is a public member profile, parsed from the page's Person JSON-LD.
type Ref ¶
type Ref struct {
Input string `json:"input"`
Kind string `json:"kind"`
ID string `json:"id"`
URL string `json:"url"`
}
Ref is the classification of a user-supplied input (the `id` command output).
type Store ¶
type Store struct {
// contains filtered or unexported fields
}
Store is a pure-Go SQLite store for parsed records.
func (*Store) CountsByKind ¶
CountsByKind returns a map of record kind to count.