# Introduction
## Install package
```shell
pip install linkedin_cat
```
## Preparation
- create file `linkedin_cookies.json`
- please use Chrome Extension `EditThisCookie` to export linkedin cookies to `linkedin_cookies.json`
## Example Usage:
## - Linkedin Send Message
```python
from linkedin_cat.message import LinkedinMessage
# linkedin cookie file path
linkedin_cookies_json='./linkedin_cookies.json'
# headless mode
headless = False
# Ininialized LinkedinMessage
bot = LinkedinMessage(linkedin_cookies_json,headless)
# message to sent, use FIRSTNAME or FULLNAME to customized the message
message = "Hello FIRSTNAME,hope you are doing well. Glad to e-meet with you on linkedin"
# Send single request by url
url = "https://www.linkedin.com/in/chandlersong/"
bot.send_single_request(url,message)
# Send multi request by linkedin url list
urls_list = [
"https://www.linkedin.com/in/chandlersong/",
"https://www.linkedin.com/in/chandlersong/",
]
bot.send_multi_request(urls_list,message)
```
## - Linkedin Search
```python
# linkein search
from linkedin_cat.search import LinkedinSearch
bot = LinkedinSearch(linkedin_cookies_json='cookies.json')
# 关键词搜索
results = bot.search_keywords('chandler song recruitment')
# 返回 list 结果
for result in results:
print(result)
# 按照搜索条件搜索, 自定义搜索条件
url = bot.generate_linkedin_search_url(keywords, company=None, title=None,school=None,first_name=None, last_name=None)
html = bot.open_linkedin_url(url)
results = bot.parse_linkedin_results(html)
for result in results:
print(result)
# {'name': '', 'title': '', 'location': '', 'introduction': '', 'linkedin_url': '', 'image_url': ''}
# 搜索linkedin profile,并保存为json文件
save_folder = './linkedin'
url = "https://www.linkedin.com/in/chandlersong/"
bot.search_linkedin_profile(url,save_folder)
# 批量搜索linkedin profile,并保存为json文件
save_folder = './linkedin'
url_list = [
"https://www.linkedin.com/in/chandlersong/"
"https://www.linkedin.com/in/chandlersong/"
"https://www.linkedin.com/in/chandlersong/"
]
bot.search_linkedin_profile_list(url_list,save_folder)
```
## Recruiter LLM
```python
import os
from jinja2 import Template
from cn_detect.detect import ChineseNameDetect
from linkedin_cat.search import LinkedinSearch # 继承了LinkedinMessage
from llm_cat.deepseek_api import deepseek_chat
# 添加自定义模块路径
# import sys
# sys.path.append(r'C:\Users\s84336076\pyfunc')
# from llm import llm
# LinkedIn cookie文件路径
linkedin_cookies_json = "cookies.json"
headless = True
token = "sk-xxxxxxxxxxxxxxxxxxxxxx"
# 创建LinkedinSearch对象
search_bot = LinkedinSearch(linkedin_cookies_json,headless=headless)
detector = ChineseNameDetect()
def judge_skill_prompt(mini_profile):
# 构建评估候选人的模板
prompt_template = """
Please assess if the candidate in #### is a security engineer.
If yes, return True; if not, return False.
Provide the response in JSON format.
example:
{
"result": True
}
\n\n
####{{ short_profile }}####
"""
template = Template(prompt_template)
prompt = template.render(short_profile=mini_profile)
# 使用LLM评估候选人
# reply = llm(prompt)
reply = deepseek_chat(prompt, token)
print(reply)
return reply
def search_recruiter(keywords, company=None, title=None, school=None, first_name=None, last_name=None,
chinese_detect=True, send_message=True, save_resume=True,
message=f"Hello FIRSTNAME, hope you are doing well. Glad to e-meet with you on LinkedIn."):
page = 1
while True:
# 生成LinkedIn搜索URL
url = search_bot.generate_linkedin_search_url(keywords, company, title, school, first_name, last_name)
if page != 1:
url += f'&page={page}'
# 打开LinkedIn URL并解析结果
html = search_bot.open_linkedin_url(url)
results = search_bot.parse_linkedin_results(html)
# 如果没有结果,退出循环
if not results:
print('No results')
break
print('Total Results:', len(results))
for result in results:
print(result)
try:
name = result['name']
url = result['linkedin_url'].split('?')[0]
mini_profile = {key: result[key] for key in ['title', 'introduction', 'location']}
# 判断linkedin是否存在
filename = search_bot.extract_username_from_linkedin_url(url) + '.json'
if os.path.exists(os.path.join('./linkedin', filename)):
print(f'{filename} already exists, skipping...')
continue
# 判断是否需要检测中文
should_continue = not chinese_detect or detector.detect_chinese_word(name) or detector.detect_family_name(name)
if should_continue:
reply = judge_skill_prompt(mini_profile)
if 'True' in reply:
# 发送消息
if send_message:
search_bot.send_single_request(url, message)
# 保存简历
if save_resume:
search_bot.search_linkedin_profile(url, thread_pool=True)
except Exception as e:
print(f"Error: {e}")
# 翻页
page += 1
# 使用示例
search_recruiter('security', company='google',last_name='jiang',send_message=False,save_resume=True)
```
Raw data
{
"_id": null,
"home_page": "https://www.linkedin.com/in/chandlersong/",
"name": "linkedin-cat",
"maintainer": null,
"docs_url": null,
"requires_python": null,
"maintainer_email": null,
"keywords": "linkedin message automation",
"author": "chandler song",
"author_email": "275737875@qq.com",
"download_url": "https://files.pythonhosted.org/packages/66/92/339fe3a33dca051970b0d9f739416dbe11b9c6a5ad54b8323437d9791c25/linkedin_cat-0.0.8.tar.gz",
"platform": "all",
"description": "\r\n# Introduction\r\n## Install package\r\n```shell\r\npip install linkedin_cat\r\n```\r\n## Preparation\r\n\r\n- create file `linkedin_cookies.json`\r\n\r\n- please use Chrome Extension `EditThisCookie` to export linkedin cookies to `linkedin_cookies.json`\r\n\r\n\r\n\r\n## Example Usage:\r\n\r\n## - Linkedin Send Message\r\n\r\n```python\r\nfrom linkedin_cat.message import LinkedinMessage\r\n\r\n# linkedin cookie file path\r\nlinkedin_cookies_json='./linkedin_cookies.json'\r\n# headless mode\r\nheadless = False\r\n# Ininialized LinkedinMessage\r\nbot = LinkedinMessage(linkedin_cookies_json,headless)\r\n\r\n# message to sent, use FIRSTNAME or FULLNAME to customized the message\r\nmessage = \"Hello FIRSTNAME,hope you are doing well. Glad to e-meet with you on linkedin\"\r\n\r\n# Send single request by url\r\nurl = \"https://www.linkedin.com/in/chandlersong/\"\r\nbot.send_single_request(url,message)\r\n\r\n# Send multi request by linkedin url list \r\nurls_list = [ \r\n \t\"https://www.linkedin.com/in/chandlersong/\",\r\n \t\"https://www.linkedin.com/in/chandlersong/\",\r\n ]\r\n\r\nbot.send_multi_request(urls_list,message)\r\n \r\n```\r\n\r\n\r\n\r\n## - Linkedin Search\r\n\r\n```python\r\n# linkein search\r\n\r\nfrom linkedin_cat.search import LinkedinSearch\r\n\r\nbot = LinkedinSearch(linkedin_cookies_json='cookies.json')\r\n\r\n# \u5173\u952e\u8bcd\u641c\u7d22\r\nresults = bot.search_keywords('chandler song recruitment') \r\n# \u8fd4\u56de list \u7ed3\u679c\r\nfor result in results:\r\n print(result)\r\n\r\n# \u6309\u7167\u641c\u7d22\u6761\u4ef6\u641c\u7d22, \u81ea\u5b9a\u4e49\u641c\u7d22\u6761\u4ef6\r\nurl = bot.generate_linkedin_search_url(keywords, company=None, title=None,school=None,first_name=None, last_name=None)\r\nhtml = bot.open_linkedin_url(url)\r\nresults = bot.parse_linkedin_results(html)\r\nfor result in results:\r\n print(result)\r\n\t# {'name': '', 'title': '', 'location': '', 'introduction': '', 'linkedin_url': '', 'image_url': ''}\r\n\r\n# \u641c\u7d22linkedin profile\uff0c\u5e76\u4fdd\u5b58\u4e3ajson\u6587\u4ef6\r\nsave_folder = './linkedin'\r\nurl = \"https://www.linkedin.com/in/chandlersong/\"\r\nbot.search_linkedin_profile(url,save_folder)\r\n\r\n# \u6279\u91cf\u641c\u7d22linkedin profile\uff0c\u5e76\u4fdd\u5b58\u4e3ajson\u6587\u4ef6\r\nsave_folder = './linkedin'\r\nurl_list = [\r\n \"https://www.linkedin.com/in/chandlersong/\"\r\n \"https://www.linkedin.com/in/chandlersong/\"\r\n \"https://www.linkedin.com/in/chandlersong/\"\r\n ]\r\n\r\nbot.search_linkedin_profile_list(url_list,save_folder)\r\n```\r\n\r\n\r\n\r\n## Recruiter LLM\r\n\r\n```python\r\nimport os\r\nfrom jinja2 import Template\r\nfrom cn_detect.detect import ChineseNameDetect\r\nfrom linkedin_cat.search import LinkedinSearch # \u7ee7\u627f\u4e86LinkedinMessage\r\nfrom llm_cat.deepseek_api import deepseek_chat\r\n\r\n# \u6dfb\u52a0\u81ea\u5b9a\u4e49\u6a21\u5757\u8def\u5f84\r\n# import sys\r\n# sys.path.append(r'C:\\Users\\s84336076\\pyfunc')\r\n# from llm import llm\r\n\r\n# LinkedIn cookie\u6587\u4ef6\u8def\u5f84\r\nlinkedin_cookies_json = \"cookies.json\"\r\nheadless = True\r\ntoken = \"sk-xxxxxxxxxxxxxxxxxxxxxx\"\r\n\r\n# \u521b\u5efaLinkedinSearch\u5bf9\u8c61\r\nsearch_bot = LinkedinSearch(linkedin_cookies_json,headless=headless)\r\ndetector = ChineseNameDetect()\r\n\r\ndef judge_skill_prompt(mini_profile):\r\n # \u6784\u5efa\u8bc4\u4f30\u5019\u9009\u4eba\u7684\u6a21\u677f\r\n prompt_template = \"\"\"\r\n Please assess if the candidate in #### is a security engineer. \r\n If yes, return True; if not, return False. \r\n Provide the response in JSON format. \r\n example:\r\n {\r\n \"result\": True\r\n }\r\n \\n\\n \r\n ####{{ short_profile }}####\r\n \"\"\"\r\n template = Template(prompt_template)\r\n prompt = template.render(short_profile=mini_profile)\r\n\r\n # \u4f7f\u7528LLM\u8bc4\u4f30\u5019\u9009\u4eba\r\n # reply = llm(prompt)\r\n reply = deepseek_chat(prompt, token)\r\n print(reply)\r\n return reply\r\n\r\n\r\ndef search_recruiter(keywords, company=None, title=None, school=None, first_name=None, last_name=None,\r\n chinese_detect=True, send_message=True, save_resume=True,\r\n message=f\"Hello FIRSTNAME, hope you are doing well. Glad to e-meet with you on LinkedIn.\"):\r\n page = 1\r\n while True:\r\n # \u751f\u6210LinkedIn\u641c\u7d22URL\r\n url = search_bot.generate_linkedin_search_url(keywords, company, title, school, first_name, last_name)\r\n if page != 1:\r\n url += f'&page={page}'\r\n\r\n # \u6253\u5f00LinkedIn URL\u5e76\u89e3\u6790\u7ed3\u679c\r\n html = search_bot.open_linkedin_url(url)\r\n results = search_bot.parse_linkedin_results(html)\r\n\r\n # \u5982\u679c\u6ca1\u6709\u7ed3\u679c\uff0c\u9000\u51fa\u5faa\u73af\r\n if not results:\r\n print('No results')\r\n break\r\n\r\n print('Total Results:', len(results))\r\n for result in results:\r\n print(result)\r\n try:\r\n name = result['name']\r\n url = result['linkedin_url'].split('?')[0]\r\n\r\n mini_profile = {key: result[key] for key in ['title', 'introduction', 'location']}\r\n\r\n # \u5224\u65adlinkedin\u662f\u5426\u5b58\u5728\r\n filename = search_bot.extract_username_from_linkedin_url(url) + '.json'\r\n if os.path.exists(os.path.join('./linkedin', filename)):\r\n print(f'{filename} already exists, skipping...')\r\n continue\r\n\r\n # \u5224\u65ad\u662f\u5426\u9700\u8981\u68c0\u6d4b\u4e2d\u6587\r\n should_continue = not chinese_detect or detector.detect_chinese_word(name) or detector.detect_family_name(name)\r\n\r\n if should_continue:\r\n reply = judge_skill_prompt(mini_profile)\r\n if 'True' in reply:\r\n # \u53d1\u9001\u6d88\u606f\r\n if send_message:\r\n search_bot.send_single_request(url, message)\r\n # \u4fdd\u5b58\u7b80\u5386\r\n if save_resume:\r\n search_bot.search_linkedin_profile(url, thread_pool=True)\r\n\r\n except Exception as e:\r\n print(f\"Error: {e}\")\r\n\r\n # \u7ffb\u9875\r\n page += 1\r\n\r\n# \u4f7f\u7528\u793a\u4f8b\r\nsearch_recruiter('security', company='google',last_name='jiang',send_message=False,save_resume=True)\r\n```\r\n\r\n\r\n\r\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "linkedin automation tool",
"version": "0.0.8",
"project_urls": {
"Homepage": "https://www.linkedin.com/in/chandlersong/"
},
"split_keywords": [
"linkedin",
"message",
"automation"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "6692339fe3a33dca051970b0d9f739416dbe11b9c6a5ad54b8323437d9791c25",
"md5": "9fd28784efcba67f24cf353e9ce7a2e5",
"sha256": "3839991df3e92eea0cd110567bdcc30c6a0405df1c9686088188a0a1952d407c"
},
"downloads": -1,
"filename": "linkedin_cat-0.0.8.tar.gz",
"has_sig": false,
"md5_digest": "9fd28784efcba67f24cf353e9ce7a2e5",
"packagetype": "sdist",
"python_version": "source",
"requires_python": null,
"size": 28663,
"upload_time": "2024-12-17T16:12:24",
"upload_time_iso_8601": "2024-12-17T16:12:24.836315Z",
"url": "https://files.pythonhosted.org/packages/66/92/339fe3a33dca051970b0d9f739416dbe11b9c6a5ad54b8323437d9791c25/linkedin_cat-0.0.8.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-12-17 16:12:24",
"github": false,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"lcname": "linkedin-cat"
}