Python爬虫实战:获取51job职位信息,并做数据分析

注意:以下内容仅供技术研究,请遵守目标网站的robots.txt规定,控制请求频率避免对目标服务器造成过大压力!

1. 环境准备

python

python 复制代码
import requests
from bs4 import BeautifulSoup
import pandas as pd
import re
import matplotlib.pyplot as plt

2. 爬虫核心代码(带反爬策略)

python

python 复制代码
def fetch_51job_data(keyword, max_pages=5):
    jobs = []
    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',
        'Accept-Language': 'zh-CN,zh;q=0.9'
    }
    
    for page in range(1, max_pages+1):
        url = f'https://search.51job.com/list/000000,000000,0000,00,9,99,{keyword},2,{page}.html'
        try:
            response = requests.get(url, headers=headers, timeout=10)
            response.encoding = 'gbk'  # 网站编码特殊处理
            soup = BeautifulSoup(response.text, 'lxml')
            
            for item in soup.select('.j_joblist .e'):
                title = item.select_one('.jname').text.strip()
                company = item.select_one('.cname').text.strip()
                desc = item.select_one('.text').text.strip()
                experience = item.select_one('.exp').text.strip() if item.select_one('.exp') else '不限'
                salary = item.select_one('.sal').text.strip()
                
                jobs.append({
                    '职位名称': title,
                    '公司名称': company,
                    '工作内容': desc,
                    '工作经验': experience,
                    '薪资范围': salary
                })
        except Exception as e:
            print(f'第{page}页抓取失败:', e)
        # 添加延迟避免被封
        time.sleep(1.5)
    
    return jobs

3. 薪资解析算法

python

python 复制代码
def parse_salary(salary_str):
    """
    支持格式示例:
    - 1.5-2万/月
    - 20-30万/年
    - 5-8千/月
    - 200-300元/天
    """
    pattern = r'(\d+\.?\d*)-(\d+\.?\d*)(万|千|元)/(年|月|日)'
    match = re.search(pattern, salary_str)
    if not match: return None

    low, high, unit, period = match.groups()
    low, high = float(low), float(high)
    avg = (low + high) / 2

    # 转换为万元/年
    conversion = {
        ('万', '年'): avg,
        ('万', '月'): avg * 12,
        ('千', '月'): avg * 12 * 0.1,
        ('元', '日'): avg * 22 * 12 / 10000
    }
    return conversion.get((unit, period), None)

4. 数据存储与清洗

python

python 复制代码
# 数据清洗管道
def clean_data(jobs):
    df = pd.DataFrame(jobs)
    df['平均年薪'] = df['薪资范围'].apply(parse_salary)
    df = df.dropna(subset=['平均年薪'])  # 过滤无效数据
    return df

# 保存到CSV
df.to_csv('51job.csv', index=False, encoding='utf-8-sig')

5. 数据分析与可视化

python

python 复制代码
def analyze_salary(df):
    # 薪资TOP10分析
    top10 = df.sort_values('平均年薪', ascending=False).head(10)
    
    # 可视化配置
    plt.style.use('ggplot')
    plt.figure(figsize=(12,8))
    bars = plt.barh(top10['职位名称'], top10['平均年薪'], color='#4BACC6')
    
    # 添加数据标签
    for bar in bars:
        width = bar.get_width()
        plt.text(width+0.5, bar.get_y()+0.2, f'{width:.1f}万', va='center')
    
    plt.title('高薪职位TOP10(单位:万元/年)', fontsize=14)
    plt.xlabel('平均年薪', fontsize=12)
    plt.gca().invert_yaxis()  # 反转Y轴显示排名
    plt.tight_layout()
    plt.savefig('salary_top10.png', dpi=300)
    plt.show()

6. 完整执行流程

python

python 复制代码
if __name__ == '__main__':
    # 数据采集
    raw_data = fetch_51job_data('python', max_pages=5)
    
    # 数据清洗
    cleaned_df = clean_data(raw_data)
    
    # 存储结果
    cleaned_df.to_csv('51job.csv', index=False, encoding='utf-8-sig')
    
    # 数据分析与可视化
    analyze_salary(cleaned_df)

7. 关键要点扩展

  1. 反爬策略强化

    • 代理IP池:使用requests-ip-rotator库实现自动IP切换

    • 浏览器指纹:通过selenium-wire模拟真实浏览器环境

    • 请求随机化:添加随机延迟(0.5-3秒)和随机User-Agent

  2. 数据质量优化

    • 异常值过滤:设置薪资合理范围(如0.5<薪资<500万/年)

    • 文本清洗:使用jieba分词提取技能要求关键词

    • 地址解析:从工作内容中提取工作地点信息

  3. 分析维度扩展

    python

    python 复制代码
    # 企业规模与薪资关系
    df['公司规模'] = df['公司名称'].apply(detect_company_size)  # 需自定义企业规模识别函数
    df.boxplot(column='平均年薪', by='公司规模')
    
    # 技能需求词云
    from wordcloud import WordCloud
    skills = extract_skills(df['工作内容'])  # 需自定义技能提取函数
    wordcloud = WordCloud().generate(' '.join(skills))
    plt.imshow(wordcloud)
  4. 架构升级思路

    • 使用Scrapy框架实现分布式爬虫

    • 集成Airflow实现定时数据更新

    • 数据存储改用MySQL+Redis缓存

    • 使用Tableau实现动态数据看板

8. 常见问题解决方案

  1. 页面结构变化

    • 定期运行监控脚本检查CSS选择器有效性

    • 使用XPath代替CSS选择器提高容错性

    • 建立元素匹配的备选方案列表

  2. 验证码破解

    • 对接打码平台(如超级鹰)

    • 使用CNN训练验证码识别模型

    • 设置验证码触发后的等待策略

  3. 数据更新机制

    python

    python 复制代码
    # 增量更新示例
    existing = pd.read_csv('51job.csv')
    new_data = fetch_new_data()
    updated = pd.concat([existing, new_data]).drop_duplicates(
        subset=['职位名称', '公司名称'], 
        keep='last'
    )
相关推荐
数据大魔方11 分钟前
【期货量化实战】跨期套利策略:价差交易完整指南(TqSdk源码详解)
数据库·python·算法·github·程序员创富
大、男人25 分钟前
python之contextmanager
android·python·adb
毕设源码-钟学长1 小时前
【开题答辩全过程】以 基于Python的车辆管理系统为例,包含答辩的问题和答案
开发语言·python
CCPC不拿奖不改名1 小时前
数据处理与分析:数据可视化的面试习题
开发语言·python·信息可视化·面试·职场和发展
液态不合群1 小时前
线程池和高并发
开发语言·python
旦莫1 小时前
Pytest教程:Pytest与主流测试框架对比
人工智能·python·pytest
数据大魔方2 小时前
【期货量化实战】螺纹钢量化交易指南:品种特性与策略实战(TqSdk完整方案)
python·算法·github·程序员创富·期货程序化·期货量化·交易策略实战
旻璿gg2 小时前
paddleocr、paddleocrvl、ppocrv5
python
清水白石0082 小时前
手写超速 CSV 解析器:利用 multiprocessing 与 mmap 实现 10 倍 Pandas 加速
python·pandas
Corleo2 小时前
记录一次复杂的 ONNX 到 TensorRT 动态 Shape 转换排错过程
python·ai