一、前言
这几年互联网名词层出不穷,比如:“降本增效”、“内卷”、“996”,“大模型”、“AI Agent”、“区块链”、“”年薪骨折、“前端已死”、“裁员潮”等等。如今互联网公司的主题基本都是降本增效和提升系统稳定性。岗位晋升不仅看武功,还有你的战功,人多肉少,竞争激烈。晋升进度放缓,p6以上晋升异常困难,要求比之前高太多。校招HC个数和待遇都比较谨慎,甚至有些应届生P4起,可能4-5年才能升到P6,比之前难太多了。
本文将通过Python以及使用Bright Data 代理 对 BOSS直聘 招聘平台进行数据抓取,并结合 PandasAI 来分析当前互联网岗位的薪资动态与职位趋势。
二、抓取目标
抓取城市:北京(100010000,可以改成其他城市id)
抓取关键字:前端
抓取网址:www.zhipin.com/web/geek/jo…
抓取字段:
- 职位名称:每个岗位的职称薪资:职位的薪资信息,包括区间和单位公司名称:提供该职位的公司名称公司福利:职位提供的福利待遇是否为实习岗位:标识岗位是否为实习职位薪资范围:具体的薪资区间,如 10K-15K学历:包括本科、大专、研究生、博士、不限制学历等技能:岗位必备的技能城市:岗位城市关键字:搜索关键字
三、通过Python爬取BOSS直聘岗位现状
本文我用 Python 编写爬虫脚本。
1、爬虫使用的核心技术
(1)使用 代理IP 解决IP封禁问题
在没有实现代理IP时,我频繁请求BOSS直聘,出现了BOSS直聘页面打不开了。
通过百度以及AI问询,最重选择了代理IP方案来解决这个问题,使用代理真的非常重要!因为在大量请求的情况下,爬虫很容易被目标网站检测并封禁,这里我使用动态住宅代理,它可以实现动态IP隐匿轮换、地理级精准定位和真人行为模拟,依托真实住宅IP网络及智能路由技术实现,从而避免封禁。
比较了市场上的住宅代理工具,最终使用Bright Data住宅代理作为本文爬取数据的工具,它可穿透复杂反爬机制,保障高频请求下的持续匿名访问与数据可靠性,按流量进行计费,并且性价比非常高!爬虫中使用代理的逻辑如下:
# 代理列表proxy = "http://brd-customer-hl_0ddaad4b-zone-residential_proxy1:whpu1pzpm7kh@brd.superproxy.io:33335", # 替换为你的代理地址# 设置代理的函数def set_proxy(): # 使用 Selenium 配置代理 chrome_options = Options() chrome_options.add_argument(f'--proxy-server={proxy}') # 配置代理 # 使用 Selenium 的 webdriver 创建浏览器实例 driver = webdriver.Chrome(options=chrome_options) return driver
(2)通过 Selenium 来模拟浏览器访问BOSS直聘
Selenium 可以模拟浏览器的操作,点击按钮、填写表单、滚动页面、获取页面元素等。
- 打开浏览器并加载页面:通过 webdriver.Chrome() 启动一个浏览器实例,打开 BOSS 直聘页面。模拟下滑操作:为了加载更多职位数据,我们使用 driver.execute_script() 方法将页面滚动到底部,触发新的数据加载。获取页面内容:爬取页面的数据通过 driver.page_source 获取。
(3)PandasAI
PandasAI 是一个开源项目,旨在为 Pandas 库添加人工智能功能,使用户能够通过自然语言与数据进行交互,并且根据自然语言提示进行复杂的数据分析,在几秒钟内完成原本需要花费数分钟的数据处理任务,所以这里我选择PandasAI对爬取的数据进行分析。
2、准备工作
(1)注册账号
进入用户控制面板之后,点击左侧第一个菜单“Proxies & Scraping”
,然后右侧可以看到“动态住宅IP”
,点击“开始使用”
接下来就是创建动态住宅代理
了
创建之后,就可以看到动态住宅代理的访问信息,如下:
(2)安装所需库
首先,我们需要安装以下执行脚本需要的库:
- Selenium:用于模拟浏览器自动化操作。pandasai:数据分析numpy:Python的一种开源的数值计算扩展
可以通过以下命令安装所需库:
- 安装爬取数据需要的库
pip3 install selenium
- 安装数据分析需要的库
pip3 install "pandasai>=3.0.0b5" numpy==1.23.0
注意:pandasai、numpy建议安装我上面的版本,不然很容易遇到兼容性问题
如果没有安装python包的话,记得安装一下,建议安装3版本,安装完查看一下版本是否安装成功,我的版本:Python 3.9.6
# 查看python版本python3 --version
(3)安装 ChromeDriver
为了让 Selenium 能够控制 Chrome 浏览器,需要安装与您的 Chrome 浏览器版本匹配的 ChromeDriver。可以在 sites.google.com/a/chromium.… 下载,ChromeDriver 必须和你的Chrome浏览器保持一致。
注意:我的浏览器版本为136.0.7103.93,但是网上找到的也只有136.0.7103.92的版本
。后来在知乎上了解到92和93是同一时间发布的,92版本的driver在93版本的浏览器也可以使用。好的,那么下面是下载连接。其他版本的连接也和这个差不多,你只需要修改连接里面的版本号就行。
ChromeDriver 136.0.7103.92下载地址:storage.googleapis.com/chrome-for-…
3、代码分析
以下是详细的代码分析,逐步解释每个部分的功能和实现:
3.1 代理设置与浏览器启动
我们首先设置代理 IP,并通过 Selenium 启动一个 Chrome 浏览器实例。这样可以模拟浏览器行为,同时使用代理 IP 避免频繁请求被封禁。
# 设置代理proxy = "http://brd-customer-hl_d10f8a55-zone-residential_proxy1:t3s2y5je88uu@brd.superproxy.io:33335"# 配置def set_proxy(): # 使用 Selenium 配置代理 chrome_options = Options() chrome_options.add_argument(f'--proxy-server={proxy}') # 配置代理 driver_path = "/Users/zbs/bawei/chromedriver-mac-arm64/chromedriver # 我的chromedriver 地址 driver = webdriver.Chrome(service=Service(driver_path), options=chrome_options) return driver
3.2 用户输入和数据初始化
用户可以输入多个搜索关键词,爬虫会根据这些关键词进行爬取。爬取的数据将存储在 job_data 列表中。
keywords = input("请输入多个关键字,关键字之间用逗号分隔:").split(',')job_data = []
3.3 翻页操作与数据抓取
对于每个关键词,我们构建翻页 URL 并依次抓取数据。每一页的 URL 都包含一个 page 参数,我们循环遍历页面。
for page in range(1, 21): # 爬取 21 页数据 url = f'https://www.zhipin.com/web/geek/job?query={keyword}&city=100010000&page={page}' driver.get(url) # 下滑页面,触发加载更多职位 driver.execute_script("window.scrollTo(0, document.body.scrollHeight);") random_sleep(2, 5) # 加入随机延迟,避免过快被检测
3.4 获取页面内容与解析
页面加载完成后,我们获取页面源代码,并尝试解析 JSON 数据。由于 BOSS直聘 网站是通过 AJAX 异步加载数据,我们需要解析 JSON 数据来提取职位信息。
# 获取页面内容并解析json_data = driver.page_sourcetry: json_data = json.loads(json_data) # 解析 JSON 格式的数据except json.JSONDecodeError as e: print(f"JSON解析错误: {e}") continue
3.5 数据提取与处理
从每个职位中提取相关信息:薪资、公司名称、职位名称等。薪资信息需要通过正则表达式进行处理。
def process_salary(salaries): salary_month = '0' match_month = re.search(r'·(\d+)薪', salaries) if match_month: salary_month = match_month.group(1) salaries = salaries.replace(match_month.group(0), '') match_salary = re.search(r'(\d+)-(\d+)([Kk元])', salaries) if match_salary: low = int(match_salary.group(1)) high = int(match_salary.group(2)) unit = match_salary.group(3) if unit.upper() == 'K': low *= 1000 high *= 1000 return f"[{low},{high}]", salary_month return '', salary_month
3.6 保存数据到 CSV
将抓取到的职位数据保存到 CSV 文件中,便于后续分析。我们使用 Pandas
库来完成这一任务。
# 将数据保存为 CSV 文件df = pd.DataFrame(job_data)df.to_csv('job_data.csv', index=False)print("数据已成功爬取并保存为 'job_data.csv'")
3.7 pandasai 处理csv文件
我们可以将抓取到的岗位数据用PandasAI进行分析,它能够处理各种自然语言处理任务,包括对话管理、信息提取、内容生成、任务自动化等,更快地从数据中获取洞察。(1)登录PandasAI ,获取密钥
(2)新建 pand.py文件,导入 PandasAI 并设置您的 API 密钥:
import pandasai as pai# Get your API key from https://app.pandabi.aipai.api_key.set("YOUR_PANDABI_API_KEY")
密钥可以在PandaBI主页的“API Keys”菜单中获取
(3)加载本地csv文件因为我们上面生成的是excel文件,只需要另存为.csv格式的文件保存即可
# Load your CSV filefile = pai.read_csv("./job_data.csv")
(4)创建和推送数据集
# Save your dataset configurationdf = pai.create( path="pai-personal-65f7b/dataset-name", df=file, description="Describe your dataset")# Push your dataset to PandaBIdf.push()
4、执行代码
控制台输入:
python3 bos.py
接着提示输入关键字:前端
爬完结束输出:数据已成功爬取并保存为 'job_data.csv'
打开生成的csv文件,查看数据
点击上面的URL之后,可以看到PandasAI已经对我们的数据进行了简单的处理。
5、源码
from selenium import webdriverfrom selenium.webdriver.chrome.options import Optionsfrom selenium.webdriver.chrome.service import Serviceimport randomimport timeimport pandas as pdimport jsonimport reimport pandasai as pai# 代理列表proxy="http://brd-customer-hl_0ddaad4b-zone-residential_proxy1:whpu1pzpm7kh@brd.superproxy.io:33335", # 替换为你的代理地址# 设置代理的函数def set_proxy(): # 使用 Selenium 配置代理 chrome_options = Options() chrome_options.add_argument(f'--proxy-server={proxy}') # 配置代理 # 使用 Selenium 的 webdriver 创建浏览器实例 driver_path = "/Users/zbs/bawei/chromedriver-mac-arm64/chromedriver" # 启动浏览器 driver = webdriver.Chrome(service=Service(driver_path), options=chrome_options) # driver = webdiver.Chrome(options=chrome_options) return driver# 随机等待函数def random_sleep(min_time=2, max_time=5): sleep_time = random.uniform(min_time, max_time) print(f"随机等待 {sleep_time:.2f} 秒...") time.sleep(sleep_time)# 处理薪资信息def process_salary(salaries): salary_month = '0' match_month = re.search(r'·(\d+)薪', salaries) if match_month: salary_month = match_month.group(1) salaries = salaries.replace(match_month.group(0), '') match_salary = re.search(r'(\d+)-(\d+)([Kk元])', salaries) if match_salary: low = int(match_salary.group(1)) high = int(match_salary.group(2)) unit = match_salary.group(3) if unit.upper() == 'K': low *= 1000 high *= 1000 return f"[{low},{high}]", salary_month return '', salary_month# 设置并打开浏览器driver = set_proxy()# 接收用户输入的多个关键字keywords = input("请输入多个关键字,关键字之间用逗号分隔:").split(',')# 初始化爬取的数据列表job_data = []# 遍历每个关键字for keyword in keywords: keyword = keyword.strip() if not keyword: continue print(f"正在采集关键字 '{keyword}' 的数据") # 构建循环翻页 for page in range(1, 20): # 只爬取 5 页数据 url = f'https://www.zhipin.com/web/geek/job?query={keyword}&city=100010000&page={page}' print(f'正在采集第 {page} 页的数据内容:{url}') driver.get(url) # 下滑页面到底部 driver.execute_script("window.scrollTo(0, document.body.scrollHeight);") random_sleep(2, 5) # 加入随机延迟 # 获取页面内容并解析 json_data = driver.page_source try: # 如果页面源代码是JSON格式(有时Ajax请求返回数据是JSON),则解析它 json_data = json.loads(json_data) except json.JSONDecodeError as e: print(f"JSON解析错误: {e}") continue if 'zpData' in json_data and 'jobList' in json_data['zpData']: jobList = json_data['zpData']['jobList'] # 遍历职位列表,提取信息 for job in jobList: salaries = job['salaryDesc'] salary, salaryMonth = process_salary(salaries) job_name = job['jobName'] company_name = job['brandName'] company_benefits = ','.join(job['welfareList']) if job['welfareList'] else '无' pratice = 0 if '实习' in job_name else 1 job_data.append({ '公司名': company_name, '职位名': job_name, '薪资': salaries, '薪资范围': salary, '年底多薪': salaryMonth, '公司福利': company_benefits, '是否为实习': pratice, '关键字': keyword }) else: print("数据格式不正确,未找到预期的字段:'zpData' 或 'jobList'") continue# 关闭浏览器driver.quit()# 保存数据为 Excel 文件df = pd.DataFrame(job_data)df.to_excel('job_data.xlsx', index=False)print("数据已成功爬取并保存为 'job_data.xlsx'")# 设置 API 密钥pai.api_key.set("PAI-6336c59c-f9c6-4e1d-bde7-f22f602eeecb")# 读取 CSV 文件file = pai.read_csv("./job_data.csv")# 创建并保存数据集配置df = pai.create( path="pai-personal-65f7b/dataset-name", df=file, description="Describe your dataset")# 推送数据集到 PandaBIdf.push()
四、数据分析
接下来,我们通过PandasAI 对数据粉进行分析,它可以根据用户询问的内容进行洞察,最终可以以图表形式进行分析。
问题1:我想知道哪些技能在北京前端岗位中最常见
提示词:哪些技能在北京前端岗位中最常见?
在北京前端岗位中,最常见的技能包括:
- Vue - 出现频率为221次前端开发经验 - 出现频率为136次React - 出现频率为130次JavaScript - 出现频率为110次CSS - 出现频率为98次
Vue 是最受欢迎的前端框架,显示出其在市场上的强大需求。前端开发经验 作为一个技能要求,强调了雇主对有经验候选人的偏好。React 和 JavaScript 也在前端开发中占据重要地位,表明这些技能在求职市场上同样受到重视。CSS 作为基础技能,仍然是前端开发不可或缺的一部分。
问题2:我想知道3-5年经验的岗位平均薪资是多少
提示词:请帮我分析一下北京前端岗位数据,3-5年经验的岗位平均薪资是多少?
据分析结果,北京前端岗位中,具有3-5年工作经验的岗位平均薪资为 16,974.75元。在北京的前端岗位中,3-5年经验的薪资水平相对较高,显示出这一经验阶段的市场需求。
问题3:我想要一份北京前端的市场趋势报告
提示词:请分析一下北京前端岗位数据,输出一份关于北京前端岗位的市场趋势报告,包括:工作经验、平均薪资(计算所有岗位的平均薪资,单个岗位的薪资按薪资范围的中间值进行计算)、热门技能(提取实习岗位中的热门技能,统计每个技能出现的频率,并找出出现频率最高的技能)、学历要求分布、实习岗位比例。”
五、使用住宅代理的一些亮点
在爬取数据过程中,我们使用 住宅代理 发现以下特点:
- ip不仅仅是动态的,并且是真实的,有明确的地理位置的经纬度。相当于真实的ip去请求网页,网页的反爬虫机制阻碍就大大降低了操作非常方便,选择自己的代码语言,可以直接套用,代码零修改的体验非常好响应非常迅速,几乎在零点几秒就返回数据结果安全性非常高,调用过程中没有出现任何的安全问题,因为Bright Data住宅代理来自明确同意参与的用户群,从而确保遵循至高道德标准,追求卓越质量
所以我在爬取过程没有遇到任何爬虫障碍,快速获取到数据,非常高效~
六、总结
在爬取数据过程中,使用代理IP真的是解决了我IP被封的很大一个难题,真的不能随意爬,不然很容易被封。另外通过分析爬取的数据,可以看到北京的前端岗位市场对3-5年、5-10年工作经验的需求量很大,并且Vue技术需求大于React技术,实习岗位真的是非常少,对大学生来说有一些挑战。上面数据只是参考,只要技能够硬,我相信一定可以拿到高薪工作!