python爬取boss直聘数据(selenium+xpath)
文章目录
- 一、主要目标
 - 二、开发环境
 - 三、selenium安装和驱动下载
 - 四、主要思路
 - 五、代码展示和说明
 - 1、导入相关库
 - 2、启动浏览器
 - 3、搜索框定位
 - 创建csv文件
 - 招聘页面数据解析(XPATH)
 - 总代码
 - 效果展示
 
- 六、总结
 
一、主要目标
以boss直聘为目标网站,主要目的是爬取下图中的所有信息,并将爬取到的数据进行持久化存储。(可以存储到数据库中或进行数据可视化分析用web网页进行展示,这里我就以csv形式存在了本地)

二、开发环境
python3.8
 pycharm
 Firefox
三、selenium安装和驱动下载
环境安装: pip install selenium
版本对照表(火狐的)
 https://firefox-source-docs.mozilla.org/testing/geckodriver/Support.html
浏览器驱动下载
 https://registry.npmmirror.com/binary.html?path=geckodriver/
火狐浏览器下载
 https://ftp.mozilla.org/pub/firefox/releases/
四、主要思路
- 利用selenium打开模拟浏览器,访问boss直聘首页(绕过cookie反爬)
 - 定位搜索按钮输入某职位,点击搜索
 - 在搜索结果页面,解析出现的职位信息,并保存
 - 获取多个页面,可以定位跳转至下一页的按钮(但是这个跳转我一直没成功,于是我就将请求url写成了动态的,直接发送一个新的url来代替跳转)
 
五、代码展示和说明
1、导入相关库
# 用来将爬取到的数据以csv保存到本地
import csv
from time import sleep
# 使用selenium绕过cookie反爬
from selenium import webdriver
from selenium.webdriver.firefox.service import Service
from selenium.webdriver.common.by import By
# 使用xpath进行页面数据解析
from lxml import etree 
2、启动浏览器
(有界面)
# 传入浏览器的驱动
ser = Service('./geckodriver.exe')
# 实例化一个浏览器对象
bro = webdriver.Firefox(service=ser)
# 设置隐式等待 超时时间设置为20s
bro.implicitly_wait(20)
# 让浏览器发起一个指定url请求
bro.get(urls[0])
 
(无界面)
# 1. 初始化配置无可视化界面对象
options = webdriver.FirefoxOptions()
# 2. 无界面模式
options.add_argument('-headless')
options.add_argument('--disable-gpu')# 让selenium规避被检测到的风险
options.add_argument('excludeSwitches')# 传入浏览器的驱动
ser = Service('./geckodriver.exe')# 实例化一个浏览器对象
bro = webdriver.Firefox(service=ser, options=options)# 设置隐式等待 超时时间设置为20s
bro.implicitly_wait(20)# 让浏览器发起一个指定url请求
bro.get(urls[0])
 
3、搜索框定位
进入浏览器,按F12进入开发者模式
 
 然后分析下图可知,搜索框和搜索按钮都有唯一的class值
 
 然后输入搜索内容,并跳转,代码如下
# 定位搜索框 .ipt-search
search_tag = bro.find_element(By.CSS_SELECTOR, value='.ipt-search')
# 输入搜索内容
search_tag.send_keys("")# 定位搜索按钮    .代表的是当前标签下的class
btn = bro.find_element(By.CSS_SELECTOR, value='.btn-search')
# 点击搜索按钮
btn.click()
 
创建csv文件
一开始编码为utf-8,但在本地打开内容是乱码,然后改成utf-8_sig就ok了
# f = open("boos直聘.csv", "w", encoding="utf-8", newline="")
f = open("boos直聘.csv", "w", encoding="utf-8_sig", newline="")
csv.writer(f).writerow(["职位", "位置", "薪资", "联系人", "经验", "公司名", "类型", "职位技能", "福利", "详情页"]) 
招聘页面数据解析(XPATH)
通过分析可知,招聘数据全在ul标签下的li标签中
 
 我们要获取的信息有这些,接下来就要进入li标签中,一个一个去分析
 
 其中职位名称在span标签中,而span标签的class有唯一的值job-name
 其它数据分析方式和这个相同
 
 数据解析代码如下
def parse():# 临时存放获取到的信息jobList = []# 提取信息page_text = bro.page_source# 将从互联网上获取的源码数据加载到tree对象中tree = etree.HTML(page_text)job = tree.xpath('//div[@class="search-job-result"]/ul/li')for i in job:# 职位job_name = i.xpath(".//span[@class='job-name']/text()")[0]# 位置jobArea = i.xpath(".//span[@class='job-area']/text()")[0]# 联系人linkman_list = i.xpath(".//div[@class='info-public']//text()")linkman = "·".join(linkman_list)# 详情页urldetail_url = prefix + i.xpath(".//h3[@class='company-name']/a/@href")[0]# print(detail_url)# 薪资salary = i.xpath(".//span[@class='salary']/text()")[0]# 经验job_lable_list = i.xpath(".//ul[@class='tag-list']//text()")job_lables = " ".join(job_lable_list)# 公司名company = i.xpath(".//h3[@class='company-name']/a/text()")[0]# 公司类型和人数等companyScale_list = i.xpath(".//div[@class='company-info']/ul//text()")companyScale = " ".join(companyScale_list)# 职位技能skill_list = i.xpath("./div[2]/ul//text()")skills = " ".join(skill_list)# 福利 如有全勤奖补贴等try:job_desc = i.xpath(".//div[@class='info-desc']/text()")[0]# print(type(info_desc))except:job_desc = ""# print(type(info_desc))# print(job_name, jobArea, salary, linkman, salaryScale, name, componyScale, tags, info_desc)# 将数据写入csvcsv.writer(f).writerow([job_name, jobArea, salary, linkman, job_lables, company, companyScale, skills, job_desc, detail_url])# 将数据存入数组中jobList.append({"jobName": job_name,"jobArea": jobArea,"salary": salary,"linkman": linkman,"jobLables": job_lables,"company": company,"companyScale": companyScale,"skills": skills,"job_desc": job_desc,"detailUrl": detail_url,})return {"jobList": jobList} 
总代码
import csv
from time import sleep
from selenium import webdriver
from selenium.webdriver.firefox.service import Service
from selenium.webdriver.common.by import By
from lxml import etree# 指定url
urls = ['https://www.zhipin.com/', 'https://www.zhipin.com/web/geek/job?query={}&page={}']
prefix = 'https://www.zhipin.com'# 1. 初始化配置无可视化界面对象
options = webdriver.FirefoxOptions()
# 2. 无界面模式
options.add_argument('-headless')
options.add_argument('--disable-gpu')# 让selenium规避被检测到的风险
options.add_argument('excludeSwitches')# 传入浏览器的驱动
ser = Service('./geckodriver.exe')# 实例化一个浏览器对象
bro = webdriver.Firefox(service=ser, options=options)
# bro = webdriver.Firefox(service=ser# 设置隐式等待 超时时间设置为20s
# bro.implicitly_wait(20)# 让浏览器发起一个指定url请求
bro.get(urls[0])sleep(6)# 定位搜索框 .ipt-search
search_tag = bro.find_element(By.CSS_SELECTOR, value='.ipt-search')
# 输入搜索内容
search_tag.send_keys("")# 定位搜索按钮    .代表的是当前标签下的class
btn = bro.find_element(By.CSS_SELECTOR, value='.btn-search')
# 点击搜索按钮
btn.click()
sleep(15)# f = open("boos直聘.csv", "w", encoding="utf-8", newline="")
f = open("boos直聘.csv", "w", encoding="utf-8_sig", newline="")
csv.writer(f).writerow(["职位", "位置", "薪资", "联系人", "经验", "公司名", "类型", "职位技能", "福利", "详情页"])def parse():# 临时存放获取到的信息jobList = []# 提取信息page_text = bro.page_source# 将从互联网上获取的源码数据加载到tree对象中tree = etree.HTML(page_text)job = tree.xpath('//div[@class="search-job-result"]/ul/li')for i in job:# 职位job_name = i.xpath(".//span[@class='job-name']/text()")[0]# 位置jobArea = i.xpath(".//span[@class='job-area']/text()")[0]# 联系人linkman_list = i.xpath(".//div[@class='info-public']//text()")linkman = "·".join(linkman_list)# 详情页urldetail_url = prefix + i.xpath(".//h3[@class='company-name']/a/@href")[0]# print(detail_url)# 薪资salary = i.xpath(".//span[@class='salary']/text()")[0]# 经验job_lable_list = i.xpath(".//ul[@class='tag-list']//text()")job_lables = " ".join(job_lable_list)# 公司名company = i.xpath(".//h3[@class='company-name']/a/text()")[0]# 公司类型和人数等companyScale_list = i.xpath(".//div[@class='company-info']/ul//text()")companyScale = " ".join(companyScale_list)# 职位技能skill_list = i.xpath("./div[2]/ul//text()")skills = " ".join(skill_list)# 福利 如有全勤奖补贴等try:job_desc = i.xpath(".//div[@class='info-desc']/text()")[0]# print(type(info_desc))except:job_desc = ""# print(type(info_desc))# print(job_name, jobArea, salary, linkman, salaryScale, name, componyScale, tags, info_desc)# 将数据写入csvcsv.writer(f).writerow([job_name, jobArea, salary, linkman, job_lables, company, companyScale, skills, job_desc, detail_url])# 将数据存入数组中jobList.append({"jobName": job_name,"jobArea": jobArea,"salary": salary,"linkman": linkman,"jobLables": job_lables,"company": company,"companyScale": companyScale,"skills": skills,"job_desc": job_desc,"detailUrl": detail_url,})return {"jobList": jobList}if __name__ == '__main__':# 访问第一页jobList = parse()query = ""# 访问剩下的九页for i in range(2, 11):print(f"第{i}页")url = urls[1].format(query, i)bro.get(url)sleep(15)jobList = parse()# 关闭浏览器bro.quit() 
效果展示

六、总结
不知道是boss反爬做的太好,还是我个人太菜(哭~)
 我个人倾向于第二种
 这个爬虫还有很多很多的不足之处,比如在页面加载的时候,boss的页面会多次加载(这里我很是不理解,我明明只访问了一次,但是他能加载好多次),这就导致是不是ip就会被封…
 再比如,那个下一页的点击按钮,一直点不了,不知有没有路过的大佬指点一二(呜呜呜~)
 
# 下一页标签定位 ui-icon-arrow-right
next_tag = bro.find_element(By.CSS_SELECTOR, value='.ui-icon-arrow-right')
# action = ActionChains(bro)
# # 点击指定的标签
# action.click(next_tag).perform()
# sleep(0.1)
# # 释放动作链
# action.release().perform()
 
总之boss的信息爬取,我还是无法做到完全自动化😭
相关文章:
python爬取boss直聘数据(selenium+xpath)
文章目录 一、主要目标二、开发环境三、selenium安装和驱动下载四、主要思路五、代码展示和说明1、导入相关库2、启动浏览器3、搜索框定位创建csv文件招聘页面数据解析(XPATH)总代码效果展示 六、总结 一、主要目标 以boss直聘为目标网站,主要目的是爬取下图中的所…...
GEO生信数据挖掘(六)实践案例——四分类结核病基因数据预处理分析
前面五节,我们使用阿尔兹海默症数据做了一个数据预处理案例,包括如下内容: GEO生信数据挖掘(一)数据集下载和初步观察 GEO生信数据挖掘(二)下载基因芯片平台文件及注释 GEO生信数据挖掘&…...
8.Mobilenetv2网络代码实现
代码如下: import math import os import numpy as npimport torch import torch.nn as nn import torch.utils.model_zoo as model_zoo#1.建立带有bn的卷积网络 def conv_bn(inp, oup, stride):return nn.Sequential(nn.Conv2d(inp,oup,3,stride,biasFalse),nn.Bat…...
Spring Boot Controller
刚入门小白,详细请看这篇SpringBoot各种Controller写法_springboot controller-CSDN博客 Spring Boot 提供了Controller和RestController两种注解。 Controller 返回一个string,其内容就是指向的html文件名称。 Controller public class HelloControll…...
在网络安全、爬虫和HTTP协议中的重要性和应用
1. Socks5代理:保障多协议安全传输 Socks5代理是一种功能强大的代理协议,支持多种网络协议,包括HTTP、HTTPS和FTP。相比之下,Socks5代理提供了更高的安全性和功能性,包括: 多协议支持: Socks5代…...
Web测试框架SeleniumBase
首先,SeleniumBase支持 pip安装: > pip install seleniumbase它依赖的库比较多,包括pytest、nose这些第三方单元测试框架,是为更方便的运行测试用例,因为这两个测试框架是支持unittest测试用例的执行的。 Seleniu…...
jvm打破砂锅问到底- 为什么要标记或记录跨代引用
为什么要标记或记录跨代引用. ygc时, 直接把老年代引用的新生代对象(可能是对象区域)记录下来当做根, 这其实就是依据第二假说和第三假说, 强者恒强, 跨代引用少(存在互相引用关系的两个对象,是应该倾 向于同时生存或者同时消亡的). 拿ygc老年代跨代引用对象当做根…...
小程序长期订阅
准备工作 ::: tip 管理后台配置 小程序类目:住建(硬性要求) 功能-》订阅消息-》我的模版 申请模版:1、预约进度通知 2、申请结果通知 3、业务办理进度提醒 ::: 用户订阅一次后,可长期下发多条消息。目前长期性订阅…...
Studio One6.5中文版本版下载及功能介绍
Studio One是一款专业的音乐制作软件,由美国PreSonus公司开发。该软件提供了全面的音频编辑和混音功能,包括录制、编曲、合成、采样等多种工具,可用于制作各种类型的音乐,如流行音乐、电子音乐、摇滚乐等。 Studio One的主要特点…...
07-Zookeeper分布式一致性协议ZAB源码剖析
上一篇:06-Zookeeper选举Leader源码剖析 整个Zookeeper就是一个多节点分布式一致性算法的实现,底层采用的实现协议是ZAB。 1. ZAB协议介绍 ZAB 协议全称:Zookeeper Atomic Broadcast(Zookeeper 原子广播协议)。 Zook…...
云原生安全应用场景有哪些?
当今数字化时代,数据已经成为企业最宝贵的资产之一,而云计算作为企业数字化转型的关键技术,其安全性也日益受到重视。随着云计算技术的快速发展,云原生安全应用场景也越来越广泛,下面本文将从云原生安全应用场景出发&a…...
Step 1 搭建一个简单的渲染框架
Step 1 搭建一个简单的渲染框架 万事开头难。从萌生到自己到处看源码手抄一个mini engine出来的想法,到真正敲键盘去抄,转眼过去了很久的时间。这次大概的确是抱着认真的想法,打开VS从零开始抄代码。不知道能坚持多久呢。。。 本次的主题是搭…...
Excel 插入和提取超链接
构造超链接 HYPERLINK(D1,C1)提取超链接 Sheet页→右键→查看代码Sub link()Dim hl As HyperlinkFor Each hl In ActiveSheet.Hyperlinkshl.Range.Offset(0, 1).Value hl.AddressNext End Sub工具栏→运行→运行子过程→提取所有超链接地址参考: https://blog.cs…...
基础架构开发-操作系统、编译器、云原生、嵌入式、ic
基础架构开发-操作系统、编译器、云原生、嵌入式、ic 操作系统编译器词法分析AST语法树生成语法优化生成机器码 云原生容器开发一般遇到的岗位描述RDMA、DPDK是什么东西NFV和VNF是什么RisingWave云原生存储引擎开发实践 单片机、嵌入式雷达路线规划 ic开发 操作系统 以C和Rust…...
C++-Mongoose(3)-http-server-https-restful
1.url 结构 2.http和 http-restful区别在于对于mg_tls_opts的赋值 2.1 http和https 区分 a) port地址 static const char *s_http_addr "http://0.0.0.0:8000"; // HTTP port static const char *s_https_addr "https://0.0.0.0:8443"; // HTTP…...
git多分支、git远程仓库、ssh方式连接远程仓库、协同开发(避免冲突)、解决协同冲突(多人在同一分支开发、 合并分支)
1 git多分支 2 git远程仓库 2.1 普通开发者,使用流程 3 ssh方式连接远程仓库 4 协同开发 4.1 避免冲突 4.2 协同开发 5 解决协同冲突 5.1 多人在同一分支开发 5.2 合并分支 1 git多分支 ## 命令操作分支-1 创建分支git branch dev-2 查看分支git branch-3 分支合…...
ChatGPT或将引发现代知识体系转变
作为当下大语言模型的典型代表,ChatGPT对人类学习方式和教育发展所产生的变革效应已然引起了广泛关注。技术的快速发展在某种程度上正在“倒逼”教育领域开启更深层次的变革。在此背景下,教育从业者势必要学会准确识变、科学应变、主动求变、以变应变&am…...
【爬虫实战】用pyhon爬百度故事会专栏
一.爬虫需求 获取对应所有专栏数据;自动实现分页;多线程爬取;批量多账号爬取;保存到mysql、csv(本案例以mysql为例);保存数据时已存在就更新,无数据就添加; 二.最终效果…...
焦炭反应性及反应后强度试验方法
声明 本文是学习GB-T 4000-2017 焦炭反应性及反应后强度试验方法. 而整理的学习笔记,分享出来希望更多人受益,如果存在侵权请及时联系我们 7— 进气口; 8— 测温热电偶。 图 A.1 单点测温加热炉体结构示意图 A.3 温度控制装置 控制精度:(11003)℃。…...
链表(3):双链表
引入 我们之前学的单向链表有什么缺点呢? 缺点:后一个节点无法看到前一个节点的内容 那我们就多设置一个格子prev用来存放前面一个节点的地址,第一个节点的prev存最后一个节点的地址(一般是null) 这样一个无头双向…...
Xshell远程连接Kali(默认 | 私钥)Note版
前言:xshell远程连接,私钥连接和常规默认连接 任务一 开启ssh服务 service ssh status //查看ssh服务状态 service ssh start //开启ssh服务 update-rc.d ssh enable //开启自启动ssh服务 任务二 修改配置文件 vi /etc/ssh/ssh_config //第一…...
服务器硬防的应用场景都有哪些?
服务器硬防是指一种通过硬件设备层面的安全措施来防御服务器系统受到网络攻击的方式,避免服务器受到各种恶意攻击和网络威胁,那么,服务器硬防通常都会应用在哪些场景当中呢? 硬防服务器中一般会配备入侵检测系统和预防系统&#x…...
基于当前项目通过npm包形式暴露公共组件
1.package.sjon文件配置 其中xh-flowable就是暴露出去的npm包名 2.创建tpyes文件夹,并新增内容 3.创建package文件夹...
OkHttp 中实现断点续传 demo
在 OkHttp 中实现断点续传主要通过以下步骤完成,核心是利用 HTTP 协议的 Range 请求头指定下载范围: 实现原理 Range 请求头:向服务器请求文件的特定字节范围(如 Range: bytes1024-) 本地文件记录:保存已…...
C++ 基础特性深度解析
目录 引言 一、命名空间(namespace) C 中的命名空间 与 C 语言的对比 二、缺省参数 C 中的缺省参数 与 C 语言的对比 三、引用(reference) C 中的引用 与 C 语言的对比 四、inline(内联函数…...
Linux离线(zip方式)安装docker
目录 基础信息操作系统信息docker信息 安装实例安装步骤示例 遇到的问题问题1:修改默认工作路径启动失败问题2 找不到对应组 基础信息 操作系统信息 OS版本:CentOS 7 64位 内核版本:3.10.0 相关命令: uname -rcat /etc/os-rele…...
快刀集(1): 一刀斩断视频片头广告
一刀流:用一个简单脚本,秒杀视频片头广告,还你清爽观影体验。 1. 引子 作为一个爱生活、爱学习、爱收藏高清资源的老码农,平时写代码之余看看电影、补补片,是再正常不过的事。 电影嘛,要沉浸,…...
uniapp 小程序 学习(一)
利用Hbuilder 创建项目 运行到内置浏览器看效果 下载微信小程序 安装到Hbuilder 下载地址 :开发者工具默认安装 设置服务端口号 在Hbuilder中设置微信小程序 配置 找到运行设置,将微信开发者工具放入到Hbuilder中, 打开后出现 如下 bug 解…...
Python 训练营打卡 Day 47
注意力热力图可视化 在day 46代码的基础上,对比不同卷积层热力图可视化的结果 import torch import torch.nn as nn import torch.optim as optim from torchvision import datasets, transforms from torch.utils.data import DataLoader import matplotlib.pypl…...
消防一体化安全管控平台:构建消防“一张图”和APP统一管理
在城市的某个角落,一场突如其来的火灾打破了平静。熊熊烈火迅速蔓延,滚滚浓烟弥漫开来,周围群众的生命财产安全受到严重威胁。就在这千钧一发之际,消防救援队伍迅速行动,而豪越科技消防一体化安全管控平台构建的消防“…...
