Python 爬虫实战:利用代理 IP 获取招聘网站信息
- 2025-02-14 四川
本文字数:7761 字
阅读完需:约 25 分钟
一、前言
马上就要到一年一度的跳槽季(金三四银),应粉丝要求,这篇文章来教教大家怎么批量获取你的 “目标岗位” 招聘信息,附上代码思路和完整源码,话不多说请看下文~
二、爬取目标
爬虫目标为某招聘网站,首先可以看到博主这里没有登录注册也可以岗位信息,那接下来写代码就不用去登录:https://www.liepin.com

三、为什么要使用代理 IP?
使用代理 IP 可以带来以下好处:
匿名保护,保护隐私安全
安全采集公开数据信息
分散访问压力,提高爬取效率和稳定性。
收集不同地区或代理服务器上的数据,用于数据分析和对比。
博主使用的是亮数据家的动态住宅代理 IP,因为是住宅 IP 隐匿性更强,动态切换安全性更高,个人感觉还不错,并且可以免费使用:

四、准备工作
4.1 编程环境准备
Python:3.10
编辑器:PyCharm
第三方模块,自行安装:
pip install pandas # 数据处理
pip install requests # 网页数据爬取
pip install selenium # 自动化操作浏览器
使用 selenium 还需要安装谷歌浏览器,下载配置浏览器驱动 WebDriver,不会配置驱动的小伙伴请看这篇文章:https://blog.csdn.net/yuan2019035055/article/details/125772198
4.2 获取代理 IP
1、首先打开官网:亮数据官网

2、填写信息:

3、填写完上图中的注册页面信息,点击“新建账户”提交后,网页会显示(如下图)验证邮件已发送至注册邮箱:

4、很快就可以在注册邮箱里(如下图),找到一封名为“Bright Data - Welcome”的验证邮件,点击登录,即可直接进入产品界面,开始使用。此时完成所有注册步骤均已完成:

5、注册登录后,在控制台选择查看代理 IP 产品:

6、选择住宅代理:

7、如果特殊需求默认配置即可,然后点击添加:

8、勾选确定:

9、参考代码语言选择 Python,然后找到你的代理 IP 链接:

10、代码设置代理 IP 链接:
proxies = {
'http': '放置你的代理url',
'https': '放置你的代理url'
}
五、爬虫代码实战
5.1 翻页分析
博主通过删除 url 的参数发现,只有三个参数是有用的,city 控制:城市,currentPage 控制:页码,key 控制:关键词

那么 Python 代码中我们就可以分别传入上面三个参数:
key = 'Python爬虫工程师' # 需要检索的岗位
city_code = '410' # 城市代码(自行从官网选择城市后查找)
page_num = 1 # 爬取的页数
for currentPage in range(0,page_num):
url =f'https://www.liepin.com/zhaopin/?city={city_code}¤tPage={currentPage}&key={key}'
5.2 数据位置分析
1、我们打开网页,右键或者按 f12 点开检查,然后点击 Network,然后刷新网页:

2、根据下面图片操作找到接口中的数据:

3、点击 Headers 查看接口地址,等一下我们需要用到:

5.3 获取日志列表
下面这段代码主要用于使用 Selenium WebDriver 启动 Chrome 浏览器,访问指定的招聘网站页面,并获取该页面加载过程中的性能日志(特别是网络请求日志)。通过配置 DesiredCapabilities 和 ChromeOptions,可以定制浏览器的启动行为和日志记录偏好。最后,通过解析性能日志的 JSON 数据,可以获取到详细的网络请求信息:
# 导入Selenium WebDriver的DesiredCapabilities模块,用于设置浏览器的一些高级配置
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
# 导入Selenium的webdriver模块,用于控制浏览器
from selenium import webdriver
# 导入json模块,用于处理JSON数据
import json
def get_data(url):
# 创建一个ChromeOptions对象,用于配置Chrome浏览器的启动选项
chrome_options = webdriver.ChromeOptions()
# 添加一个实验性选项,启用W3C标准模式
chrome_options.add_experimental_option('w3c', True)
# 获取Chrome浏览器的默认配置
caps = DesiredCapabilities.CHROME
# 设置日志偏好,这里特别指定了性能日志(performance)记录所有信息
caps["goog:loggingPrefs"] = {"performance": "ALL"}
# 使用指定的配置和选项启动Chrome浏览器
driver = webdriver.Chrome(desired_capabilities=caps, options=chrome_options) # 启动浏览器
# 设置隐式等待时间,单位为秒,这里设置为8秒,用于等待页面元素加载完成
driver.implicitly_wait(8)
# 访问指定的URL
driver.get(url) # 打开网页
# 获取网络请求日志
# 通过driver.get_log('performance')获取性能日志,然后使用列表推导式解析日志中的JSON数据
logs = [json.loads(log['message'])['message'] for log in driver.get_log('performance')]
# 遍历日志列表,并打印每条日志
for log in logs:
print(log)
# 定义要访问的URL,这里是一个招聘网站的链接,搜索Python爬虫工程师
url = 'https://www.liepin.com/zhaopin/?city=410¤tPage=1&key=Python%E7%88%AC%E8%99%AB%E5%B7%A5%E7%A8%8B%E5%B8%88'
get_data(url)
运行结果,可以看到有很多请求链接:

问题来了,怎么从那么多请求信息中找到我们需要的数据接口?
通过 if 判断限制结果只返回我们刚才找到的数据接口:
# 判断限制结果只返回我们刚才找到的数据接口
if log['method'] == 'Network.responseReceived' and 'https://api-c.liepin.com/api/com.liepin.searchfront4c.pc-search-job' in log['params']['response']['url']:
print(log)
运行结果:

5.4 获取接口数据
通过日志解析,接口中的数据:
def get_data(url, data_list):
"""定义一个函数,用于从指定URL获取数据并填充到data_list列表中"""
# 创建一个ChromeOptions对象,用于配置Chrome浏览器的启动选项
chrome_options = webdriver.ChromeOptions()
# 添加一个实验性选项,启用W3C标准模式,这对于与WebDriver的交互很重要
chrome_options.add_experimental_option('w3c', True)
# 获取Chrome浏览器的默认配置
caps = DesiredCapabilities.CHROME
# 设置日志偏好,这里特别指定了性能日志(performance)记录所有信息,用于后续分析网络请求
caps["goog:loggingPrefs"] = {"performance": "ALL"}
# 使用指定的配置和选项启动Chrome浏览器
driver = webdriver.Chrome(desired_capabilities=caps, options=chrome_options) # 启动浏览器
# 设置隐式等待时间,单位为秒,这里设置为8秒,用于等待页面元素加载完成
driver.implicitly_wait(8)
# 访问指定的URL
driver.get(url) # 打开网页
# 获取网络请求日志
# 通过driver.get_log('performance')获取性能日志,然后使用列表推导式解析日志中的JSON数据
logs = [json.loads(log['message'])['message'] for log in driver.get_log('performance')]
# 遍历日志列表,并打印每条日志
for log in logs:
# 判断限制结果只返回我们刚才找到的数据接口(根据URL判断)
if log['method'] == 'Network.responseReceived' and 'https://api-c.liepin.com/api/com.liepin.searchfront4c.pc-search-job' in \
log['params']['response']['url']:
requestId = log['params']['requestId']
try:
# 使用Chrome DevTools Protocol (CDP) 获取响应体
response_dict = driver.execute_cdp_cmd('Network.getResponseBody', {'requestId': requestId})
body = response_dict["body"]
body_dict = json.loads(body) # 将响应体解析为JSON
# 尝试从JSON响应中提取具体的数据
try:
jobCardList = body_dict['data']['data']['jobCardList']
print(len(jobCardList)) # 打印找到的岗位数量
for i in jobCardList:
# 尝试提取每个岗位的具体信息,如果提取失败则设置为None
try:
compName = i['comp']['compName'] # 公司名称
except:
compName = None
try:
compScale = i['comp']['compScale'] # 公司规模
except:
compScale = None
try:
compStage = i['comp']['compStage'] # 公司发展阶段
except:
compStage = None
try:
compIndustry = i['comp']['compIndustry'] # 行业
except:
compIndustry = None
try:
title = i['job']['title'] # 岗位名称
except:
title = None
try:
salary = i['job']['salary'] # 薪资
except:
salary = None
try:
dq = i['job']['dq'] # 办公地点
except:
dq = None
try:
requireWorkYears = i['job']['requireWorkYears'] # 年限要求
except:
requireWorkYears = None
try:
requireEduLevel = i['job']['requireEduLevel'] # 学历要求
except:
requireEduLevel = None
# 打印并添加到data_list列表中
print(
{'岗位名称': title, '薪资': salary, '办公地点': dq, '年限要求': requireWorkYears, '学历要求': requireEduLevel,
'公司名称': compName, '规模': compScale, '阶段': compStage, '行业': compIndustry})
data_list.append(
{'岗位名称': title, '薪资': salary, '办公地点': dq, '年限要求': requireWorkYears, '学历要求': requireEduLevel,
'公司名称': compName, '规模': compScale, '阶段': compStage, '行业': compIndustry})
except:
print('body err!') # 如果解析JSON时出错,打印错误信息
except:
pass # 如果获取响应体时出错,则忽略
print('------------') # 打印分隔符,便于查看日志输出
运行结果打印所有数据:

5.5 将数据保存到 Excel
将获取到的数据写入 Excel:
def to_excel(data_list):
"""写入Excel"""
df = pd.DataFrame(data_list)
df.drop_duplicates() # 删除重复数据
df.to_excel('招聘信息.xlsx')
5.6 完整源码
由于招聘网站反爬虫比较厉害,多次翻页就不会返回数据了,所以我们需要给下面的函数加上 proxies 参数,需要看 4.2 获取并修改 proxies 中的代理 IP 链接。还可以修改关键词、爬取的页数和城市代码(自行从官网选择城市后查找):
# 导入Selenium WebDriver的DesiredCapabilities模块,用于设置浏览器的一些高级配置
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
# 导入Selenium的webdriver模块,用于控制浏览器
from selenium import webdriver
# 用于写入Excel文件
import pandas as pd
# 导入json模块,用于处理JSON数据
import json
import time
def get_data(url, data_list):
"""定义一个函数,用于从指定URL获取数据并填充到data_list列表中"""
# 创建一个ChromeOptions对象,用于配置Chrome浏览器的启动选项
chrome_options = webdriver.ChromeOptions()
# 添加代理IP
proxies = {
'http': '放置你的代理url', # 需要看4.2自行获取代理IP链接
'https': '放置你的代理url' # 需要看4.2自行获取代理IP链接
}
chrome_options.add_argument(f'--proxy-server=http://{proxies}')
# 添加一个实验性选项,启用W3C标准模式,这对于与WebDriver的交互很重要
chrome_options.add_experimental_option('w3c', True)
# 获取Chrome浏览器的默认配置
caps = DesiredCapabilities.CHROME
# 设置日志偏好,这里特别指定了性能日志(performance)记录所有信息,用于后续分析网络请求
caps["goog:loggingPrefs"] = {"performance": "ALL"}
# 使用指定的配置和选项启动Chrome浏览器
driver = webdriver.Chrome(desired_capabilities=caps, options=chrome_options) # 启动浏览器
# 设置隐式等待时间,单位为秒,这里设置为8秒,用于等待页面元素加载完成
driver.implicitly_wait(8)
# 访问指定的URL
driver.get(url) # 打开网页
# 获取网络请求日志
# 通过driver.get_log('performance')获取性能日志,然后使用列表推导式解析日志中的JSON数据
logs = [json.loads(log['message'])['message'] for log in driver.get_log('performance')]
# 遍历日志列表,并打印每条日志
for log in logs:
# 判断限制结果只返回我们刚才找到的数据接口(根据URL判断)
if log['method'] == 'Network.responseReceived' and 'https://api-c.liepin.com/api/com.liepin.searchfront4c.pc-search-job' in \
log['params']['response']['url']:
requestId = log['params']['requestId']
try:
# 使用Chrome DevTools Protocol (CDP) 获取响应体
response_dict = driver.execute_cdp_cmd('Network.getResponseBody', {'requestId': requestId})
body = response_dict["body"]
body_dict = json.loads(body) # 将响应体解析为JSON
# 尝试从JSON响应中提取具体的数据
try:
jobCardList = body_dict['data']['data']['jobCardList']
print(len(jobCardList)) # 打印找到的岗位数量
for i in jobCardList:
# 尝试提取每个岗位的具体信息,如果提取失败则设置为None
try:
compName = i['comp']['compName'] # 公司名称
except:
compName = None
try:
compScale = i['comp']['compScale'] # 公司规模
except:
compScale = None
try:
compStage = i['comp']['compStage'] # 公司发展阶段
except:
compStage = None
try:
compIndustry = i['comp']['compIndustry'] # 行业
except:
compIndustry = None
try:
title = i['job']['title'] # 岗位名称
except:
title = None
try:
salary = i['job']['salary'] # 薪资
except:
salary = None
try:
dq = i['job']['dq'] # 办公地点
except:
dq = None
try:
requireWorkYears = i['job']['requireWorkYears'] # 年限要求
except:
requireWorkYears = None
try:
requireEduLevel = i['job']['requireEduLevel'] # 学历要求
except:
requireEduLevel = None
# 打印并添加到data_list列表中
print(
{'岗位名称': title, '薪资': salary, '办公地点': dq, '年限要求': requireWorkYears, '学历要求': requireEduLevel,
'公司名称': compName, '规模': compScale, '阶段': compStage, '行业': compIndustry})
data_list.append(
{'岗位名称': title, '薪资': salary, '办公地点': dq, '年限要求': requireWorkYears, '学历要求': requireEduLevel,
'公司名称': compName, '规模': compScale, '阶段': compStage, '行业': compIndustry})
except:
print('body err!') # 如果解析JSON时出错,打印错误信息
except:
pass # 如果获取响应体时出错,则忽略
print('------------') # 打印分隔符,便于查看日志输出
def to_excel(data_list):
"""写入Excel"""
df = pd.DataFrame(data_list)
df.drop_duplicates() # 删除重复数据
df.to_excel('招聘信息.xlsx')
if __name__ == '__main__':
key = 'Python爬虫工程师' # 需要检索的岗位
city_code = '410' # 城市代码(自行从官网选择城市后查找)
page_num = 4 # 爬取的页数
data_list = [] # 存放数据
# 一、循环翻页
for currentPage in range(0,page_num):
url =f'https://www.liepin.com/zhaopin/?city={city_code}¤tPage={currentPage}&key={key}'
# 二、发送请求,解析数据
get_data(url,data_list)
time.sleep(2) # 限制速度
# 三、写入Excel
to_excel(data_list)
免责声明:本文爬虫思路、相关技术和代码仅用于学习参考,对阅读本文后的进行爬虫行为的用户不承担任何法律责任。
5.7 爬取结果展示
使用代理 IP 后获取数据成功,在脚本同路径下生成 Excel,我们打开来看看:

六、总结
代理 IP 对于爬虫是密不可分的,但使用代理 IP 需要遵守相关法律法规和目标网站的使用规则,不得进行非法活动或滥用代理 IP 服务。亮数据家的动态住宅代理 IP 可以帮助爬虫安全采集公开数据信息,最近更是推出了限时 5 折优惠,新老客户同享,有需要代理 IP 的小伙伴可以试试:亮数据官网

袁袁袁袁满
还未添加个人签名 2022-04-28 加入
还未添加个人简介
评论