{
"info": {
"author": "Tom Quirk",
"author_email": "tomquirkacc@gmail.com",
"bugtrack_url": null,
"classifiers": [
"License :: OSI Approved :: MIT License",
"Operating System :: OS Independent",
"Programming Language :: Python :: 3"
],
"description": "# linkedin_api\n\n\ud83d\udc68\u200d\ud83d\udcbc Python Wrapper for the Linkedin API\n\n[](https://badge.fury.io/py/linkedin-api)\n\n> No \"official\" API access required - just use a valid Linkedin account!\n\nProgrammatically send messages, perform searches, get profile data and more, all with a regular Linkedin user account!\n\n##### USE AT YOUR OWN RISK \ud83d\ude09\n\nThis project should only be used as a learning project. Using it would violate Linkedin's User Agreement. I am not responsible for your account being blocked (which they will definitely do - see User Agreement section 8.2). Hint: **don't use a Linkedin account that you care about**)\n\n## Overview\n\nThis project attempts to provide a simple Python interface for the Linkedin API.\n\n> Do you mean the [legit Linkedin API](https://developer.linkedin.com/)?\n\nNO! To retrieve structured data, the [Linkedin Website](https://linkedin.com) 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. - anything that you can see on linkedin.com, we can get from Voyager.\n\nSo specifically, this project aims to provide complete coverage for Voyager.\n\n[How do we do it?](#in-depth-overview)\n\n### Want to contribute?\n\n[Learn how to find endpoints](#to-find-endpoints)\n\n## Installation\n\n```\n$ pip install linkedin-api\n```\n\n### Example usage\n\n```python\nfrom linkedin_api import Linkedin\n\n# Authenticate using any Linkedin account credentials\napi = Linkedin('reedhoffman@linkedin.com', 'iheartmicrosoft')\n\n# GET a profile\nprofile = api.get_profile('billy-g')\n\n# GET a profiles contact info\ncontact_info = api.get_profile_contact_info('billy-g')\n\n# GET all connected profiles (1st, 2nd and 3rd degree) of a given profile\nconnections = api.get_profile_connections('1234asc12304', max_connections=200)\n```\n\n## Documentation\n\nFor a complete reference documentation, see the [DOCS.md](https://github.com/tomquirk/linkedin-api/blob/master/DOCS.md)\n\n## Development Setup\n\n### Dependencies\n\n- Python 3.7\n- A valid Linkedin user account (don't use your personal account, if possible)\n- Pipenv (optional)\n\n### Installation\n\n1. Create a `.env` config file. An example is provided in `.env.example` - you include at least all of the settings set there.\n2. Using pipenv...\n\n ```\n $ pipenv install\n $ pipenv shell\n ```\n\n### Running tests\n\n```\n$ python -m pytest tests\n```\n\n### Troubleshooting\n\n#### > I keep getting a CHALLENGE!?!\n\nLinkedin 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.\n\n##### Known reasons for Challenge:\n\n- 2FA\n- Rate-limit - \"It looks like you\u2019re visiting a very high number of pages on LinkedIn.\". Note - n=1 experiment where this page was hit after ~900 contiguous requests in a single session (within the hour) (these included random delays between each request), as well as a bunch of testing, so who knows the actual limit.\n\nPlease add more as you come across them.\n\n#### Search woes\n\n- Mileage may vary when searching general keywords like \"software\" using the standard `search` method. They've recently added some smarts around search whereby they group results by people, company, jobs etc. if the query is general enough. Try to use an entity-specific search method (i.e. search_people) where possible.\n\n\n\n## In-depth overview\n\nVoyager endpoints look like this:\n\n```\nhttps://www.linkedin.com/voyager/api/identity/profileView/tom-quirk\n```\n\nOr, more clearly\n\n```\n ___________________________________ _______________________________\n| base path | resource |\nhttps://www.linkedin.com/voyager/api /identity/profileView/tom-quirk\n```\n\nThey are authenticated with a simple cookie, which we send with every request, along with a bunch of headers.\n\nTo get a cookie, we POST a given username and password (of a valid Linkedin user account) to `https://www.linkedin.com/uas/authenticate`.\n\n\n\n### To find endpoints...\n\nWe're looking at the Linkedin website and we spot some data we want. What now?\n\nThe most reliable method to find the relevant endpoint is to:\n\n1. `view source`\n2. `command-f`/search the page for some keyword in the data. This will exist inside of a `` tag.\n3. Scroll down to the **next adjacent element** which will be another `` tag, probably with an `id` that looks something like\n ```html\n \n {\"request\":\"/voyager/api/identity/profiles/tom-quirk/profileView\",\"status\":200,\"body\":\"bpr-guid-3900675\"}\n \n ```\n4. The value of `request` is the url! :woot:\n\nYou can also use the `network` tab in you browsers developer tools, but you will encounter mixed results.\n\n### How Clients query Voyager\n\nLinkedin 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!**.\n\nHere's an example of making a request for an organisation's `name` and `groups` (the Linkedin groups it manages):\n\n```\n/voyager/api/organization/companies?decoration=(name,groups*~(entityUrn,largeLogo,groupName,memberCount,websiteUrl,url))&q=universalName&universalName=linkedin\n```\n\nThe \"querying\" happens in the `decoration` parameter, which looks like\n\n```\n(\n name,\n groups*~(entityUrn,largeLogo,groupName,memberCount,websiteUrl,url)\n)\n```\n\nSo here, we request an organisation name, and a list of groups, where for each group we want `largeLogo`, `groupName`, etc.\n\nDifferent 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.\n\nIn contrast, the `/search/cluster` endpoint uses `q=guided`, and specifies its query with the `guided` parameter, whose value is something like\n\n```\nList(v->PEOPLE)\n```\n\nIt 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).\n\n\n",
"description_content_type": "text/markdown",
"docs_url": null,
"download_url": "",
"downloads": {
"last_day": -1,
"last_month": -1,
"last_week": -1
},
"home_page": "https://github.com/tomquirk/linkedin-api",
"keywords": "",
"license": "MIT",
"maintainer": "",
"maintainer_email": "",
"name": "linkedin-api",
"package_url": "https://pypi.org/project/linkedin-api/",
"platform": "",
"project_url": "https://pypi.org/project/linkedin-api/",
"project_urls": {
"Homepage": "https://github.com/tomquirk/linkedin-api"
},
"release_url": "https://pypi.org/project/linkedin-api/1.1.0/",
"requires_dist": [
"requests"
],
"requires_python": "",
"summary": "Python wrapper for the Linkedin API",
"version": "1.1.0"
},
"last_serial": 4987032,
"releases": {
"0.0.1": [
{
"comment_text": "",
"digests": {
"md5": "0db33b30b3129e19e97ad3eb0f0c69ed",
"sha256": "eff36161f2ffefd792dce667f90743695990f54bb47c6b4ad0ca8bb7ee0478e1"
},
"downloads": -1,
"filename": "linkedin_api-0.0.1-py3-none-any.whl",
"has_sig": false,
"md5_digest": "0db33b30b3129e19e97ad3eb0f0c69ed",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": null,
"size": 7963,
"upload_time": "2018-06-30T04:23:21",
"url": "https://files.pythonhosted.org/packages/c5/f4/9bf37eb6b52d5b48c7b838aaccdce87a8dcfffc320993b292d450d750304/linkedin_api-0.0.1-py3-none-any.whl"
},
{
"comment_text": "",
"digests": {
"md5": "9b6ba09ac03c294aa3e00296ba0548b6",
"sha256": "0f58acef544b59578fd358bf969508f62c7321e84980abdc286c22e0d112ac1b"
},
"downloads": -1,
"filename": "linkedin_api-0.0.1.tar.gz",
"has_sig": false,
"md5_digest": "9b6ba09ac03c294aa3e00296ba0548b6",
"packagetype": "sdist",
"python_version": "source",
"requires_python": null,
"size": 7118,
"upload_time": "2018-06-30T04:23:23",
"url": "https://files.pythonhosted.org/packages/f9/40/344a3d58fd14799cfafc40b2fd6f4796b08d1eb17cca09ca12272c9cba4f/linkedin_api-0.0.1.tar.gz"
}
],
"0.1.0": [
{
"comment_text": "",
"digests": {
"md5": "ba984dd6a784314838bf6870dfc06dd6",
"sha256": "eea783cfe49f67879abc90499789343d13106f49793cf411c1c6fb58cb8003b6"
},
"downloads": -1,
"filename": "linkedin_api-0.1.0-py3-none-any.whl",
"has_sig": false,
"md5_digest": "ba984dd6a784314838bf6870dfc06dd6",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": null,
"size": 9456,
"upload_time": "2018-09-09T21:39:26",
"url": "https://files.pythonhosted.org/packages/db/2d/3bb9c3d49ba08da97ceb596c3ae125e0e022259fd885a5c33c9eaa3575d9/linkedin_api-0.1.0-py3-none-any.whl"
},
{
"comment_text": "",
"digests": {
"md5": "19e2a4e53320b59fe9832629b3f83c18",
"sha256": "409662aa85ff2516e8182587a4f53f516060f7c66af91c44c7d0a7419e7f3742"
},
"downloads": -1,
"filename": "linkedin_api-0.1.0.tar.gz",
"has_sig": false,
"md5_digest": "19e2a4e53320b59fe9832629b3f83c18",
"packagetype": "sdist",
"python_version": "source",
"requires_python": null,
"size": 10327,
"upload_time": "2018-09-09T21:39:29",
"url": "https://files.pythonhosted.org/packages/6c/0e/7001d325336ec0b890faf8be3ecbcf3d81471882f9395399fe3907a1c0de/linkedin_api-0.1.0.tar.gz"
}
],
"0.2.0": [
{
"comment_text": "",
"digests": {
"md5": "d23eecb08af0b068296d5ceb32761f7b",
"sha256": "4ba2740064fc85a02170b6883e7005cee8f703d6ac82b0eb2c46494b78bfd070"
},
"downloads": -1,
"filename": "linkedin_api-0.2.0-py3-none-any.whl",
"has_sig": false,
"md5_digest": "d23eecb08af0b068296d5ceb32761f7b",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": null,
"size": 10525,
"upload_time": "2019-01-24T07:29:36",
"url": "https://files.pythonhosted.org/packages/4b/86/5cc4f2db47d03eba0622e610e968255588c436d000896153bd2e24927066/linkedin_api-0.2.0-py3-none-any.whl"
},
{
"comment_text": "",
"digests": {
"md5": "a41591e624f08588a50fb5c9d2a0dc56",
"sha256": "838e7ef11fde4e2e59f77d888b0e683881858217c56d327e0731732937bc8086"
},
"downloads": -1,
"filename": "linkedin_api-0.2.0.tar.gz",
"has_sig": false,
"md5_digest": "a41591e624f08588a50fb5c9d2a0dc56",
"packagetype": "sdist",
"python_version": "source",
"requires_python": null,
"size": 10814,
"upload_time": "2019-01-24T07:29:38",
"url": "https://files.pythonhosted.org/packages/6c/b1/f4488367dd377c35ef2ee03e3c44b43a42999d9295a6eeef14bd7a4de8bd/linkedin_api-0.2.0.tar.gz"
}
],
"1.0.0": [
{
"comment_text": "",
"digests": {
"md5": "454762554dfc7a23a0d531cf242699fe",
"sha256": "2393998e5a5442ae65fe95761edc74fcea814958c86af7d87861206969d4fb97"
},
"downloads": -1,
"filename": "linkedin_api-1.0.0.tar.gz",
"has_sig": false,
"md5_digest": "454762554dfc7a23a0d531cf242699fe",
"packagetype": "sdist",
"python_version": "source",
"requires_python": null,
"size": 9425,
"upload_time": "2019-02-10T23:40:04",
"url": "https://files.pythonhosted.org/packages/4f/45/33f3177ab983b97dd561561d5e004947afd90250c11aa858d866c093b3f0/linkedin_api-1.0.0.tar.gz"
}
],
"1.0.1": [
{
"comment_text": "",
"digests": {
"md5": "5789c0533844017c441fb5d411c102f3",
"sha256": "97cc44485830d92d634bf6b88273df1756184afaef4303faa5f0aca3451851b4"
},
"downloads": -1,
"filename": "linkedin_api-1.0.1-py3-none-any.whl",
"has_sig": false,
"md5_digest": "5789c0533844017c441fb5d411c102f3",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": null,
"size": 12150,
"upload_time": "2019-02-13T21:11:43",
"url": "https://files.pythonhosted.org/packages/c1/bc/5a5eadcd4936d44cd337522289665c40024209e0b2fec345964a0196b09c/linkedin_api-1.0.1-py3-none-any.whl"
},
{
"comment_text": "",
"digests": {
"md5": "81583e6968ac098b8ad41ff511c6caa0",
"sha256": "903791ca1329c432e4dc53e3824a96a91158a099b1239d013f55b11170a9ff18"
},
"downloads": -1,
"filename": "linkedin_api-1.0.1.tar.gz",
"has_sig": false,
"md5_digest": "81583e6968ac098b8ad41ff511c6caa0",
"packagetype": "sdist",
"python_version": "source",
"requires_python": null,
"size": 13044,
"upload_time": "2019-02-13T21:11:45",
"url": "https://files.pythonhosted.org/packages/5c/cd/5852a447932bbb2d27d23cf60b54b6fda47a17f3f67c4a87a010be444e62/linkedin_api-1.0.1.tar.gz"
}
],
"1.1.0": [
{
"comment_text": "",
"digests": {
"md5": "41e2b0ca67caf4e7ea421a3ab483d306",
"sha256": "97b905e7ae7f25b69140902f6bf861427ebd0d6d7a86af682b02e537ea3efe9b"
},
"downloads": -1,
"filename": "linkedin_api-1.1.0-py3-none-any.whl",
"has_sig": false,
"md5_digest": "41e2b0ca67caf4e7ea421a3ab483d306",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": null,
"size": 12474,
"upload_time": "2019-03-26T10:28:36",
"url": "https://files.pythonhosted.org/packages/7f/bd/5204a0f94026350d9c04e1642626448a2ee94ef5529f4e4f0f2e7e393264/linkedin_api-1.1.0-py3-none-any.whl"
},
{
"comment_text": "",
"digests": {
"md5": "5392710d8f951a62db13b5c0eaeaefb2",
"sha256": "ee09ed0753d6a611ad79f7ab33be75bf505dd0f97702a123447107f219f6678a"
},
"downloads": -1,
"filename": "linkedin_api-1.1.0.tar.gz",
"has_sig": false,
"md5_digest": "5392710d8f951a62db13b5c0eaeaefb2",
"packagetype": "sdist",
"python_version": "source",
"requires_python": null,
"size": 13655,
"upload_time": "2019-03-26T10:28:38",
"url": "https://files.pythonhosted.org/packages/c2/e1/6cebaf8874d0534228310e56eefb7131e3bf11b38bb236e9b8a542741a5d/linkedin_api-1.1.0.tar.gz"
}
]
},
"urls": [
{
"comment_text": "",
"digests": {
"md5": "41e2b0ca67caf4e7ea421a3ab483d306",
"sha256": "97b905e7ae7f25b69140902f6bf861427ebd0d6d7a86af682b02e537ea3efe9b"
},
"downloads": -1,
"filename": "linkedin_api-1.1.0-py3-none-any.whl",
"has_sig": false,
"md5_digest": "41e2b0ca67caf4e7ea421a3ab483d306",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": null,
"size": 12474,
"upload_time": "2019-03-26T10:28:36",
"url": "https://files.pythonhosted.org/packages/7f/bd/5204a0f94026350d9c04e1642626448a2ee94ef5529f4e4f0f2e7e393264/linkedin_api-1.1.0-py3-none-any.whl"
},
{
"comment_text": "",
"digests": {
"md5": "5392710d8f951a62db13b5c0eaeaefb2",
"sha256": "ee09ed0753d6a611ad79f7ab33be75bf505dd0f97702a123447107f219f6678a"
},
"downloads": -1,
"filename": "linkedin_api-1.1.0.tar.gz",
"has_sig": false,
"md5_digest": "5392710d8f951a62db13b5c0eaeaefb2",
"packagetype": "sdist",
"python_version": "source",
"requires_python": null,
"size": 13655,
"upload_time": "2019-03-26T10:28:38",
"url": "https://files.pythonhosted.org/packages/c2/e1/6cebaf8874d0534228310e56eefb7131e3bf11b38bb236e9b8a542741a5d/linkedin_api-1.1.0.tar.gz"
}
]
}