linkedin-cat


Namelinkedin-cat JSON
Version 0.0.8 PyPI version JSON
download
home_pagehttps://www.linkedin.com/in/chandlersong/
Summarylinkedin automation tool
upload_time2024-12-17 16:12:24
maintainerNone
docs_urlNone
authorchandler song
requires_pythonNone
licenseMIT
keywords linkedin message automation
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            
# 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"
}
        
Elapsed time: 0.40502s