+可视化(附完整代码))
在当今数字化时代网络爬虫技术已成为数据获取的重要手段之一。本文将通过一个实际案例——采集智联招聘信息详细介绍如何使用Python和Selenium框架实现数据采集。我们将从环境准备、网页结构分析、采集字段说明到爬虫实现步骤等方面展开帮助读者快速掌握相关技术。 本文章中所有内容仅供学习交流使用不用于其他任何目的严禁用于商业用途和非法用途否则由此产生的一切后果均与作者无关本篇文章使用的是seleniunm接管已经打开的浏览器进行数据采集原理不懂的可以看之前的技术博客(selenium接管已经打开的浏览器)更新时间2026-7-21一、项目背景随着大数据技术的快速发展大数据相关岗位需求激增。为了更好地了解全国各地区大数据岗位的分布情况、薪资水平及企业需求我开发了这个基于Selenium的智联招聘爬虫项目。该项目能够自动搜索大数据相关岗位并按省份分类采集岗位详细信息为求职者、人力资源研究者和数据分析师提供有价值的数据支持。二、环境准备所需工具和库PythonSeleniumChrome浏览器ChromeDriver驱动pip install seleniumChromeDriver配置下载与本地Chrome浏览器版本匹配的ChromeDriver将ChromeDriver.exe放在指定路径或者放在anaconda根目录下不懂的直接指定路径确保Chrome浏览器已安装并可正常运行三、采集字段说明字段类别字段名称字段说明示例值岗位信息岗位名称招聘职位的名称大数据开发工程师岗位薪资职位提供的薪资范围15-25k/月岗位标签职位的福利或特点标签列表[五险一金, 年终奖, 带薪年假]工作省份职位所在的省份北京工作地点职位的具体工作城市/区域海淀区工作经验职位要求的工作年限3-5年学历要求职位要求的学历水平本科公司信息公司名字招聘企业的名称XX科技有限公司公司类型企业的所有制类型民营公司规模企业的人员规模范围1000-9999人公司行业企业所属的行业领域互联网/IT四、网页结构分析在编写爬虫之前我们需要对51job的网页结构进行分析以便准确提取所需信息。职位列表页面智联招聘对于该网页第一步应该是在搜索框输入关键字然后点击搜索第二步是选择地区然后对网页进行数据解析和数据保存。动态加载页面采用动态加载技术需要模拟浏览器操作反爬机制有一定反爬措施需要合理设置等待时间和随机延迟五、爬虫步骤分析一关键字搜索关键字搜索是整个爬虫的起始步骤通过模拟用户在智联招聘网站上的搜索行为来定位目标数据。访问初始页面首先使用bro.get()方法打开智联招聘的搜索页面基础URL为https://www.zhaopin.com/sou/jl779/p1定位搜索框通过XPath语法找到搜索输入框元素输入关键词使用send_keys(keyword)方法输入目标关键词大数据触发搜索点击搜索按钮二区域选择区域选择功能允许按省份筛选职位通过job_area(province)函数实现打开地区筛选器点击地区筛选按钮输入目标省份在地区搜索框中输入省份名称注意海南和吉林是情况不能简单的回车确认选择对于特殊省份如吉林、海南需要单独处理点击特定列表项其他省份直接按回车键确认等待结果刷新选择后等待1-2秒让页面刷新特殊处理使用WebDriverWait显式等待确保元素可交互确保按钮已经可以点击对香港、澳门、台湾地区做了跳过处理因为没有数据三数据解析和保存数据解析是核心功能通过parsel_data()函数实现1.定位职位列表本案例用的是二次提取最后一页的岗位信息标签存在不一致应该是第二套标签内容。或者直接//div[classjoblist-box__item clearfix] 这样定位就不会出现定位不到的问题2.提取岗位信息岗位名称从jobinfo__top类下的a标签获取薪资从jobinfo__salary类提取标签收集jobinfo__tag下的所有div文本3.提取公司信息公司名称从companyinfo__top类下的a标签获取公司标签解析companyinfo__tag下的div分别提取类型、规模和行业4.数据存储使用csv.DictWriter将数据写入CSV文件按实际需求进行对应的数据保存字段包括11个关键信息点对可能缺失的字段如公司类型进行异常处理四翻页定位翻页按钮使用XPath//div[classsoupager]/a[last()]找到下一页按钮执行翻页操作直接调用click()方法点击也可使用JS执行点击注释掉的execute_script方案页码追踪通过page 1记录当前页码终止条件当找不到下一页按钮时触发异常通过try-except捕获异常并终止循环建议采用click点击翻页因为最后一页点击不到就报错然后捕获异常break六、结果展示七、完整代码一数据采集爬虫部分如果你对这个项目感兴趣想要获取完整可运行的源代码欢迎在评论区留言或私信主页 \/zzxcrq1234 伪善。二可视化部分1.岗位数量地域分布地图from pyecharts import options as opts from pyecharts.charts import Map map_data df[工作省份].value_counts().reset_index().values.tolist() map_chart ( Map() .add( series_name, data_pairmap_data, maptypechina, is_map_symbol_showFalse, # 禁用标记点 label_optsopts.LabelOpts(is_showTrue, font_size8), # 调整省份字体大小 ) .set_global_opts( title_optsopts.TitleOpts(title岗位数量地域分布地图), visualmap_optsopts.VisualMapOpts( is_piecewiseTrue, # 分段显示 pieces[ {min: 300, label: 300以上, color: #FF4500}, {min: 150, max: 299, label: 150-300, color: #FFA07A}, {min: 50, max: 149, label: 50-150, color: #FFE4B5}, {min: 0, max: 49, label: 50以下, color: #FFF5E6}, ], ), ) ) map_chart.render(./可视化结果/岗位数量地域分布地图.html) map_chart.render_notebook()2 .不同学历的平均月薪education_order [ 学历不限, 初中及以下, 高中, 中专/中技, 大专, 本科, 硕士, 博士, ] avg_salary df[岗位薪资(元/月)].groupby(df[学历要求]).mean() avg_salary avg_salary.reindex(education_order) # 按学历由低到稿排列 plt.figure(figsize(8, 6)) # 设置图形大小 sns.barplot(xavg_salary.index, yavg_salary.values, paletteviridis) # 使用 seaborn 绘制柱状图 # 添加标题和标签 plt.title(不同学历的平均月薪, fontsize16) plt.xlabel() plt.ylabel() plt.savefig(./可视化结果/不同学历的平均月薪.png) # 显示图形 plt.show()3 .中国城市月薪Top 7avg_salary_city df[岗位薪资(元/月)].groupby(df[工作地点]).mean().sort_values(ascendingFalse)[:7] plt.figure(figsize(10, 6)) # 设置图形大小 sns.barplot(xavg_salary_city.values, yavg_salary_city.index, paletteviridis) # 使用 seaborn 绘制柱状图 # 添加标题和标签 plt.title(中国城市月薪Top 7, fontsize16) plt.xlabel() plt.ylabel() plt.grid(False) plt.savefig(./可视化结果/中国城市月薪Top7.png) plt.show()4. 工作经验占比分布size_counts df[工作经验].value_counts() # 主题 sns.set_theme(stylewhitegrid,rc{ font.sans-serif: [SimHei], axes.unicode_minus: False, font.family: sans-serif }) plt.figure(figsize(8, 8)) # 设置画布大小 plt.pie( size_counts, # 数据 labelssize_counts.index, # 标签 autopct%1.1f%%, # 显示百分比 startangle90, # 起始角度 colorssns.color_palette(pastel), # 使用 Seaborn 的 pastel 调色板 wedgeprops{edgecolor: white, linewidth: 1.5}, # 设置扇形边缘样式 textprops{fontsize: 12, color: black} # 设置文本样式 ) plt.title(工作经验占比分布, fontsize16, fontweightbold, pad20) plt.savefig(./可视化结果/工作经验占比分布.png) plt.show()5.企业规模占比分布6.企业类型占比分布7.岗位标签词云from wordcloud import WordCloud import jieba all_text .join(df[岗位标签]) words jieba.lcut(all_text) all_text .join(words) wordcloud WordCloud( font_pathsimhei.ttf, # 设置字体路径支持中文 width800, height600, background_colorwhite, # 设置背景颜色 max_words100, # 设置最多显示的词数 min_font_size10, # 设置最小字体大小 max_font_size100, # 设置最大字体大小 random_state42 # 设置随机种子 ).generate(all_text) plt.figure(figsize(10, 8)) plt.imshow(wordcloud, interpolationbilinear) plt.axis(off) # 关闭坐标轴 plt.title(, fontsize16) plt.savefig(./可视化结果/岗位标签词云.png) plt.show()