Python wrapper for the Linkedin API
Project description
linkedin_api
👨💼 Python Wrapper for the Linkedin API
No "official" API access required - just use a valid Linkedin account!
Programmatically send messages, perform searchs, get profile data and more, all with only your Linkedin account!
USE AT YOUR OWN RISK 😉
This project should only be used as a learning project. Using it would violate Linkedin's Terms of Use. I am not responsible for your account being blocked (which they will definitely do. Hint: don't use your personal Linkedin account)
Overview
This project attempts to provide a simple Python interface for the Linkedin API.
Do you mean the legit Linkedin API?
NO! To retrieve structured data, the Linkedin Website uses a service they call Voyager. Voyager endpoints give us access to pretty much everything we could want from Linkedin: profiles, companies, connections, messages, etc.
So specifically, this project aims to provide complete coverage for Voyager.
Want to contribute?
Installation
$ pip install linkedin-api
Example usage
from linkedin_api import Linkedin
# Authenticate using any Linkedin account credentials
api = Linkedin('reedhoffman@linkedin.com', 'iheartmicrosoft')
# GET a profile
profile = api.get_profile('billy-g')
# GET a profiles contact info
contact_info = api.get_profile_contact_info('billy-g')
# GET all connected profiles (1st, 2nd and 3rd degree) of a given profile
connections = api.get_profile_connections('1234asc12304', max_connections=200)
Documentation
For a complete reference documentation, see the DOCS.md
Setup
Dependencies
- Python 3
- A valid Linkedin user account (don't use your personal account, if possible)
- Pipenv (optional)
-
Using pipenv...
$ pipenv install $ pipenv shell
Troubleshooting
> I can't authenticate - I keep getting a CHALLENGE!?!
Linkedin will throw you a curve ball in the form of a challenge URL. We currently don't handle this, and so you're kinda screwed. We think it could be only IP-based (i.e. logging in from different location). Your best chance at resolution is to log out and log back in on your browser.
In-depth overview
Voyager endpoints look like this:
https://www.linkedin.com/voyager/api/identity/profileView/tom-quirk
Or, more clearly
___________________________________ _______________________________
| base path | resource |
https://www.linkedin.com/voyager/api /identity/profileView/tom-quirk
They are authenticated with a simple cookie, which we send with every request, along with a bunch of headers.
To get a cookie, we POST a given username and password (of a valid Linkedin user account) to https://www.linkedin.com/uas/authenticate.
To find endpoints...
We're looking at the Linkedin website and we spot some data we want. What now?
The most reliable method to find the relevant endpoint is to:
view sourcecommand-f/search the page for some keyword in the data. This will exist inside of a<code>tag.- Scroll down to the next adjacent element which will be another
<code>tag, probably with anidthat looks something like<code style="display: none" id="datalet-bpr-guid-3900675"> {"request":"/voyager/api/identity/profiles/tom-quirk/profileView","status":200,"body":"bpr-guid-3900675"} </code>
- The value of
requestis the url! :woot:
You can also use the network tab in you browsers developer tools, but you will encounter mixed results.
How Clients query Voyager
Linkedin seems to have developed an internal query language/syntax where Clients (i.e. front-ends like linkedin.com) to specify what data they want (similar to the GraphQL concept). If anyone knows what this is, I'd love to know!.
Here's an example of making a request for an organisation's name and groups (the Linkedin groups it manages):
/voyager/api/organization/companies?decoration=(name,groups*~(entityUrn,largeLogo,groupName,memberCount,websiteUrl,url))&q=universalName&universalName=linkedin
The "querying" happens in the decoration parameter, which looks like
(
name,
groups*~(entityUrn,largeLogo,groupName,memberCount,websiteUrl,url)
)
So here, we request an organisation name, and a list of groups, where for each group we want largeLogo, groupName, etc.
Different endpoints use different parameters (and perhaps even different syntaxes) to specify these queries. Notice that the above query had a parameter q whose value was universalName; the query was then specified with the decoration parameter.
In contrast, the /search/cluster endpoint uses q=guided, and specifies its query with the guided parameter, whose value is something like
List(v->PEOPLE)
It could be possible to document (and implement a nice interface for) this query language - as we add more endpoints to this project, I'm sure it will become more clear if such a thing would be possible (and if it's worth it).
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file linkedin_api-0.2.0.tar.gz.
File metadata
- Download URL: linkedin_api-0.2.0.tar.gz
- Upload date:
- Size: 10.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/1.12.1 pkginfo/1.5.0.1 requests/2.21.0 setuptools/40.6.3 requests-toolbelt/0.8.0 tqdm/4.29.1 CPython/3.7.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
838e7ef11fde4e2e59f77d888b0e683881858217c56d327e0731732937bc8086
|
|
| MD5 |
a41591e624f08588a50fb5c9d2a0dc56
|
|
| BLAKE2b-256 |
6cb1f4488367dd377c35ef2ee03e3c44b43a42999d9295a6eeef14bd7a4de8bd
|
File details
Details for the file linkedin_api-0.2.0-py3-none-any.whl.
File metadata
- Download URL: linkedin_api-0.2.0-py3-none-any.whl
- Upload date:
- Size: 10.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/1.12.1 pkginfo/1.5.0.1 requests/2.21.0 setuptools/40.6.3 requests-toolbelt/0.8.0 tqdm/4.29.1 CPython/3.7.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4ba2740064fc85a02170b6883e7005cee8f703d6ac82b0eb2c46494b78bfd070
|
|
| MD5 |
d23eecb08af0b068296d5ceb32761f7b
|
|
| BLAKE2b-256 |
4b865cc4f2db47d03eba0622e610e968255588c436d000896153bd2e24927066
|