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 jsonimport 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 加入
还未添加个人简介









评论