python实战-用海外代理IP抓LinkedIn热门岗位数据

最近我身边也有个小伙伴在做全球热门岗位趋势分析,想看看LinkedIn 上美国、德国这些国家都在招啥?技术岗多还是市场岗?到底啥技能最吃香?

传统找工作更多是"看到什么投什么",但如果你想系统地回答这些问题:

  • 哪些城市/国家,某个方向岗位最多?
  • Python / Go / 数据分析 / AI Agent 之类的技能,在哪些地区需求正在上升?
  • 远程岗位更集中在哪些时区?

就需要对岗位数据做更精细的采集与分析。

所以今天我们就实战一把:用 Python + 海外代理 IP,搞定 LinkedIn 热门岗位数据采集,并顺存成表格分析热门岗位与技能趋势。通过这种方式,我们可以从更广阔的视角洞察全球职场动态,从而提前布局。

1 为什么海外代理 IP 对求职洞察很重要?

类似我小伙伴一样,很多人打开LinkedIn准备大干一场的时候,立马踩坑:

一访问就跳登录页------同一IP频繁切换地址,网站做出的自我保护机制;

"怎么感觉国外也没那么多 Python 岗位啊?"------看到的是"本地化 + 个性化"的一小块视图,而不是不同地区的"原生视角";

访问频率一高就提示"请求异常"在同一IP下大量高频搜索,很快就会触发人机校验。

这时候,海外代理IP就变成一个绕不开的话题,海外代理IP允许分散请求,模拟自然用户行为;而且此类平台的供需也非常具有地区差异,例如北美岗位更注重科技技能,而欧洲可能强调可持续发展主题。使用海外代理可以访问特定地区的本地化数据,可以让我们更全面地触达这些需求。

2 准备工作

2.1 先装好环境,主角是 requests + BeautifulSoup

bash 复制代码
pip install requests beautifulsoup4 pandas

2.2 再准备一些代理 IP(可以临时拿测试 IP,看自己用的顺手的):

python 复制代码
# 功能:发送带青果网络海外代理IP的请求
def get_proxy():
proxy_url = "https://overseas.proxy.qg.net/get?key=yourkey&num=1&area=&isp=&format=txt&seq=\r\n&distinct=false" # 青果网络海外代理IP API地址"  

2.3 页面结构快速看一眼

随便搜一下 data analyst,跳转到这个 URL:

bash 复制代码
https://www.linkedin.com/jobs/search/?keywords=data%20analyst&location=United%20States&start=0

参数拆一下:

参数名 含义
keywords 搜索关键词(可 URL 编码)
location 地点,比如 United States
start 分页,从 0 开始,每页 25 条

这玩意就一"拼 URL 模板"的事儿,后续我们一页页改 start=25、50、75... 去翻页就行。

3 实战环节

3.1 初始化配置(关键词、页数、输出文件)

bash 复制代码
KEYWORD = "data analyst"
LOCATION = "United States"
PAGES = 3
OUTPUT = "linkedin_jobs.csv"

3.2 随机选择代理 + 请求头设置

python 复制代码
import random

def get_proxy():
    return random.choice(proxies_list)

headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)"
}

记得设置 UA,不然容易被判定成脚本行为。

3.3 主函数:爬取岗位数据

python 复制代码
import requests
from bs4 import BeautifulSoup
import pandas as pd
import random
import time
import os

# ========== 可配置区域 ==========
KEYWORD = "data analyst"
LOCATION = "United States"
PAGES = 5
OUTPUT_FILE = "linkedin_jobs_usa.csv"

# 带青果网络海外代理IP的请求
def get_proxy():
proxy_url = "https://overseas.proxy.qg.net/get?key=yourkey&num=1&area=&isp=&format=txt&seq=\r\n&distinct=false" # 青果网络海外代理IP API地址" 

USER_AGENTS = [
    "Mozilla/5.0 (Windows NT 10.0; Win64; x64)",
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)",
    "Mozilla/5.0 (X11; Linux x86_64)"
]

# ========== 工具函数 ==========
def get_proxy():
    return random.choice(proxies_list)

def get_headers():
    return {
        "User-Agent": random.choice(USER_AGENTS),
        "Accept-Language": "en-US,en;q=0.9"
    }

# ========== 主爬虫函数 ==========
def scrape_jobs(keyword, location, pages):
    results = []

    for page in range(pages):
        start = page * 25
        url = f"https://www.linkedin.com/jobs/search/?keywords={keyword}&location={location}&start={start}"
        print(f"\n➡️ 正在抓取第 {page + 1} 页: {url}")

        retry = 0
        while retry < 3:
            try:
                proxy = get_proxy()
                headers = get_headers()
                print(f"使用代理: {proxy['http']},UA: {headers['User-Agent']}")
                resp = requests.get(url, headers=headers, proxies=proxy, timeout=10)
                resp.raise_for_status()
                soup = BeautifulSoup(resp.text, "html.parser")
                jobs = soup.select("div.base-card")

                for job in jobs:
                    try:
                        title = job.select_one("h3").get_text(strip=True) if job.select_one("h3") else ""
                        company = job.select_one("h4").get_text(strip=True) if job.select_one("h4") else ""
                        location = job.select_one(".job-search-card__location").get_text(strip=True) if job.select_one(".job-search-card__location") else ""
                        link = job.select_one("a")["href"].split("?")[0] if job.select_one("a") else ""

                        results.append({
                            "Title": title,
                            "Company": company,
                            "Location": location,
                            "Link": link
                        })
                    except Exception as parse_err:
                        print("⚠️ 单条解析失败,已跳过")

                break  # 成功就跳出 retry
            except Exception as e:
                retry += 1
                wait = 2 ** retry
                print(f"❌ 抓取失败(第 {retry} 次):{e},{wait} 秒后重试...")
                time.sleep(wait)

        time.sleep(random.uniform(3, 6))

    return results

# ========== 启动爬虫 ==========
if __name__ == '__main__':
    data = scrape_jobs(KEYWORD, LOCATION, PAGES)
    df = pd.DataFrame(data)
    df.drop_duplicates(inplace=True)
    df.to_csv(OUTPUT_FILE, index=False)
    print(f"\n✅ 共抓取 {len(df)} 条岗位信息,保存到:{os.path.abspath(OUTPUT_FILE)}")

3.4 保存到 CSV

python 复制代码
import pandas as pd

data = scrape_jobs(KEYWORD, LOCATION, PAGES)
df = pd.DataFrame(data)
df.drop_duplicates(inplace=True)
df.to_csv(OUTPUT, index=False)
print(f"✅ 一共抓到 {len(df)} 条,已保存到 {OUTPUT}")

4 运行效果

运行后你会看到这样一批数据(CSV 可直接丢到 Excel 分析):

Title Company Location Link
Data Analyst Netflix California linkedin的链接1
BI Engineer Amazon New York linkedin的链接2

5 清洗数据

有了原始数据,并不代表你已经能直接分析了。通常还需要几步加工。

比如:岗位标题是个非常"自由"的字段:

  • Senior Python Developer
  • Python Engineer
  • Backend Engineer (Python)
  • Fullstack Developer (Python, React)

你如果直接按标题分组统计,会发现每个城市的"Top 岗位"都是一大堆看起来类似但名字不一样的东西。

所以我们可以将标题归一化:

  • 把标题转小写,去掉公司花字、标点;

  • 识别出核心词汇:python + developer/engineer/backend/fullstack

  • 映射到内部定义的"标准岗位族":

    • 全部归到 Python Backend Developer 或更粗粒度的 Python Developer

还可以根据地区、时间序列进行分析,技术需求是涨了还是少了,加入薪资、福利等字段,然后制作成图表。

6 写在最后

如果只从技术的角度看,python加上海外代理IP可以玩出很多花样,具体就要看整体的采集思路是否正确。而且优质的代理IP是根本,不然你代码写得再好看,没毛病,也是无法走通的。海外代理IP服务选择时,可以重点关注是否有合规说明,别用一办,直接跑路了,以及,国人的产品还是会比海外的好使一点,毕竟交流沟通无障碍,不然等老外那个时差邮件来回倒腾,黄花菜都凉了。

相关推荐
用户3458482850536 分钟前
python在使用synchronized关键字时,需要注意哪些细节问题?
后端
代码扳手40 分钟前
Golang 高效内网文件传输实战:零拷贝、断点续传与 Protobuf 指令解析(含完整源码)
后端·go
undsky1 小时前
【RuoYi-Eggjs】:让 MySQL 更简单
后端·node.js
程序员西西1 小时前
Spring Boot整合MyBatis调用存储过程?
java·后端
whltaoin1 小时前
【 手撕Java源码专栏 】Spirng篇之手撕SpringBean:(包含Bean扫描、注册、实例化、获取)
java·后端·spring·bean生命周期·手撕源码
第二只羽毛1 小时前
遵守robots协议的友好爬虫
大数据·爬虫·python·算法·网络爬虫
好难取啊1 小时前
[python学习]案例01:随机验证码与账号密码修改
python
一枚ABAPer1 小时前
SAP ABAP 如何读取FTP读取CSV文件到内表
后端
秋邱1 小时前
价值升维!公益赋能 + 绿色技术 + 终身学习,构建可持续教育 AI 生态
网络·数据库·人工智能·redis·python·学习·docker