首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >实战:爬取某联招聘职位需求并生成词云——从零开始的完整指南

实战:爬取某联招聘职位需求并生成词云——从零开始的完整指南

原创
作者头像
富贵软件
发布2025-11-28 15:24:40
发布2025-11-28 15:24:40
1140
举报
文章被收录于专栏:编程教程编程教程

一、项目背景:为什么我们要做这件事?

在求职季,你是否曾对着成百上千的招聘信息发呆?HR每天要筛选数百份简历,求职者要在海量岗位中找方向。如果能用技术手段快速提取岗位核心需求,无论是求职者优化简历还是企业分析人才市场,都能事半功倍。

本文将手把手教你用Python爬取某联招聘的职位需求,并通过词云可视化展示高频关键词。整个过程分为三个阶段:数据采集(爬虫)、数据处理(清洗)、数据可视化(词云),即使没有编程基础也能跟着操作。

二、工具准备:需要哪些武器?

1. 开发环境

  • Python 3.8+(推荐Anaconda集成环境)
  • 代码编辑器:VS Code/PyCharm(选你顺手的)
  • 浏览器:Chrome(用于查看网页结构)

2. 核心库安装

代码语言:javascript
复制
pip install requests beautifulsoup4 pandas wordcloud jieba matplotlib
  • requests:发送HTTP请求
  • BeautifulSoup:解析HTML
  • pandas:数据处理
  • wordcloud:生成词云
  • jieba:中文分词
  • matplotlib:绘图展示

3. 辅助工具

  • 代理IP池(应对反爬)
  • Chrome开发者工具(按F12打开)

三、数据采集:突破反爬陷阱

1. 目标分析

打开某联招聘官网(https://www.***.com),以"Python开发"为例搜索:

  1. 观察URL结构:https://sou.***.com/?kw=Python开发&page=1
  2. 翻页规律:每页参数page递增
  3. 职位列表容器:通过开发者工具找到.job-list ul li

2. 基础爬虫代码

代码语言:javascript
复制
import requests
from bs4 import BeautifulSoup

def get_job_list(keyword, page):
    url = f"https://sou.***.com/?kw={keyword}&page={page}"
    headers = {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36"
    }
    try:
        response = requests.get(url, headers=headers, timeout=10)
        if response.status_code == 200:
            soup = BeautifulSoup(response.text, 'html.parser')
            jobs = []
            for li in soup.select('.job-list ul li'):
                title = li.select_one('.job-title').text.strip()
                company = li.select_one('.company-name').text.strip()
                salary = li.select_one('.salary').text.strip() if li.select_one('.salary') else "面议"
                requirement = li.select_one('.job-requirements').text.strip() if li.select_one('.job-requirements') else ""
                jobs.append({
                    'title': title,
                    'company': company,
                    'salary': salary,
                    'requirement': requirement
                })
            return jobs
        else:
            print(f"请求失败,状态码:{response.status_code}")
            return []
    except Exception as e:
        print(f"发生错误:{e}")
        return []

3. 反爬策略升级

问题1:直接请求返回403

  • 解决方案:添加更多请求头字段 headers = { "User-Agent": "...", "Referer": "https://www.***.com/", "Accept-Language": "zh-CN,zh;q=0.9", "Cookie": "你的浏览器cookie(可选)" }

问题2:频繁请求被封IP

  • 解决方案:使用代理IP池 import random proxies = [ {"http": "http://123.123.123.123:8080"}, {"http": "http://124.124.124.124:8081"} ] response = requests.get(url, headers=headers, proxies=random.choice(proxies), timeout=10)

进阶技巧

  • 使用time.sleep(random.uniform(1,3))添加随机延迟
  • 购买付费代理服务(如快代理、芝麻代理)
  • 分布式爬取(多线程/多进程)

4. 完整采集流程

代码语言:javascript
复制
def crawl_all_pages(keyword, max_pages=5):
    all_jobs = []
    for page in range(1, max_pages+1):
        print(f"正在爬取第{page}页...")
        jobs = get_job_list(keyword, page)
        if not jobs:
            break
        all_jobs.extend(jobs)
        time.sleep(2)  # 礼貌性延迟
    return all_jobs

# 执行爬取
jobs_data = crawl_all_pages("Python开发", 3)

四、数据处理:提取核心需求

1. 数据清洗

代码语言:javascript
复制
import pandas as pd

df = pd.DataFrame(jobs_data)
# 去除空值
df = df.dropna(subset=['requirement'])
# 保存原始数据(可选)
df.to_csv('zhaopin_raw.csv', index=False, encoding='utf_8_sig')

2. 需求文本提取

观察发现,职位描述通常包含:

  • 岗位职责(以"岗位职责:"开头)
  • 任职要求(以"任职要求:"开头)
  • 其他信息(公司福利等) def extract_requirements(text): if not text: return "" # 简单分割(实际可能需要更复杂的正则) parts = text.split('任职要求:') if len(parts) > 1: return parts[1].split('职位福利:')[0].strip() else: return text.split('岗位职责:')[-1].split('职位福利:')[0].strip() df['clean_require'] = df['requirement'].apply(extract_requirements)

3. 合并所有需求文本

代码语言:javascript
复制
all_requirements = ' '.join(df['clean_require'].tolist())

五、词云生成:可视化核心技能

1. 中文分词处理

代码语言:javascript
复制
import jieba

# 添加自定义词典(可选)
jieba.load_userdict("tech_terms.txt")  # 可自行准备技术术语词典

# 分词并过滤停用词
stopwords = set()
with open('stopwords.txt', 'r', encoding='utf-8') as f:  # 停用词表
    for line in f:
        stopwords.add(line.strip())

words = [word for word in jieba.cut(all_requirements) 
         if len(word) > 1 and word not in stopwords and not word.isspace()]
word_str = ' '.join(words)

2. 生成词云

代码语言:javascript
复制
from wordcloud import WordCloud
import matplotlib.pyplot as plt

# 设置词云参数
wc = WordCloud(
    font_path='simhei.ttf',  # 中文字体文件路径
    background_color='white',
    width=800,
    height=600,
    max_words=100,
    max_font_size=100
)

# 生成词云
wc.generate(word_str)

# 显示词云
plt.figure(figsize=(10, 8))
plt.imshow(wc, interpolation='bilinear')
plt.axis('off')
plt.savefig('zhaopin_wordcloud.png', dpi=300, bbox_inches='tight')
plt.show()

3. 结果优化技巧

  • 调整形状:使用图片蒙版(需Pillow库) from PIL import Image import numpy as np mask = np.array(Image.open("python_logo.png")) wc = WordCloud(mask=mask, ...)
  • 颜色定制:通过colormap参数选择matplotlib配色方案
  • 词频统计:用collections.Counter查看高频词

六、完整代码整合

代码语言:javascript
复制
import requests
from bs4 import BeautifulSoup
import pandas as pd
import jieba
from wordcloud import WordCloud
import matplotlib.pyplot as plt
import time
import random

# 1. 数据采集
def get_job_list(keyword, page):
    url = f"https://sou.***.com/?kw={keyword}&page={page}"
    headers = {
        "User-Agent": "Mozilla/5.0...",
        "Referer": "https://www.***.com/"
    }
    try:
        response = requests.get(url, headers=headers, timeout=10)
        if response.status_code == 200:
            soup = BeautifulSoup(response.text, 'html.parser')
            jobs = []
            for li in soup.select('.job-list ul li'):
                # 解析逻辑同上...
            return jobs
        return []
    except:
        return []

# 2. 数据处理
def process_data(jobs_data):
    df = pd.DataFrame(jobs_data)
    df = df.dropna(subset=['requirement'])
    
    def extract_req(text):
        # 提取逻辑同上...
        pass
    
    df['clean_require'] = df['requirement'].apply(extract_req)
    all_text = ' '.join(df['clean_require'].tolist())
    return all_text

# 3. 生成词云
def generate_wordcloud(text):
    stopwords = set(['可以', '能够', '具有', '等'])  # 示例停用词
    words = [word for word in jieba.cut(text) 
             if len(word) > 1 and word not in stopwords]
    
    wc = WordCloud(
        font_path='simhei.ttf',
        width=800,
        height=600
    ).generate(' '.join(words))
    
    plt.figure(figsize=(10, 8))
    plt.imshow(wc)
    plt.axis('off')
    plt.savefig('output.png')
    plt.show()

# 主流程
if __name__ == "__main__":
    keyword = "Python开发"
    jobs = []
    for page in range(1, 4):
        jobs.extend(get_job_list(keyword, page))
        time.sleep(2)
    
    text = process_data(jobs)
    generate_wordcloud(text)

七、常见问题Q&A

Q1:被网站封IP怎么办? A:立即启用备用代理池,建议使用住宅代理(如站大爷IP代理),配合每请求更换IP策略。更稳妥的方式是购买付费代理服务,这类代理通常有更高的匿名度和稳定性。

Q2:如何获取更精准的职位描述? A:某联招聘的HTML结构可能变化,建议:

  1. 按F12打开开发者工具
  2. 在Elements面板搜索关键词如"职责"
  3. 更新CSS选择器路径(如.job-description > p

Q3:词云中出现无关词汇怎么过滤? A:三步解决:

  1. 扩充停用词表(添加"工作"、"经验"等常见词)
  2. 在分词后添加词性过滤(保留名词/动词)
  3. 设置min_font_size参数过滤低频词

Q4:如何爬取其他招聘网站? A:核心流程相同,需注意:

  1. 分析目标网站的URL结构
  2. 调整CSS选择器匹配新页面
  3. 可能需要处理验证码(建议使用打码平台)

Q5:代码运行报错怎么办? A:按这个顺序排查:

  1. 检查网络连接是否正常
  2. 确认目标网站是否改版(更新选择器)
  3. 查看完整错误信息(用try-except捕获异常)
  4. 在GitHub搜索类似错误解决方案

八、进阶建议

  1. 定时任务:用schedule库实现每天自动爬取
  2. 数据存储:将结果存入MySQL/MongoDB
  3. 分析扩展:统计不同城市的技能需求差异
  4. 部署上线:用Flask搭建简单数据看板

通过这个项目,你不仅掌握了网络爬虫和数据分析的基本技能,更重要的是建立了从数据采集到价值输出的完整思维链条。下次面对海量招聘信息时,你就可以用代码快速提炼关键信息,让技术真正服务于实际需求。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、项目背景:为什么我们要做这件事?
  • 二、工具准备:需要哪些武器?
    • 1. 开发环境
    • 2. 核心库安装
    • 3. 辅助工具
  • 三、数据采集:突破反爬陷阱
    • 1. 目标分析
    • 2. 基础爬虫代码
    • 3. 反爬策略升级
    • 4. 完整采集流程
  • 四、数据处理:提取核心需求
    • 1. 数据清洗
    • 2. 需求文本提取
    • 3. 合并所有需求文本
  • 五、词云生成:可视化核心技能
    • 1. 中文分词处理
    • 2. 生成词云
    • 3. 结果优化技巧
  • 六、完整代码整合
  • 七、常见问题Q&A
  • 八、进阶建议
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档