Python 爬虫实战案例 – 获取BOSS直聘网招聘职位信息
引言
在当今竞争激烈的职场环境中,无论是求职者渴望找到理想工作,还是企业力求招揽优秀人才,精准、及时的招聘信息都至关重要。BOSS 直聘作为国内知名的在线招聘平台,汇聚了海量的职位资源,涵盖各行各业、各个层级。对于求职者,这里宛如一座蕴藏无限机会的宝库,能助其快速锚定契合自身发展的岗位;对于企业,它则是发现千里马的优质猎场,可精准匹配所需人才。
而 Python 爬虫技术恰似一把神奇钥匙,能开启这座宝库的大门,让我们高效地获取其中的招聘职位信息。通过合理运用爬虫,我们可以突破手动浏览的局限,按照设定的规则批量抓取职位名称、薪资范围、公司名称、工作地点等关键数据,并进行深入分析,为求职决策、行业研究、人才战略制定等提供有力的数据支撑。
接下来,就让我们看看如何运用 Python 爬虫获取关键的招聘信息。
一、实战目标
本次实战的核心目标是精准抓取BOSS直聘网特定职位的关键招聘信息。具体而言,要获取的信息涵盖:职位名称,薪资范围,公司名称,工作区域信息。
二、技术路线
requests:用于发送HTTP请求,获取网页内容。
BeautifulSoup:用于解析HTML页面,提取所需的信息。
csv:用于将爬取的数据存储为CSV文件,便于后续分析。
三、数据爬取
3.1 网页分析
在代码编写之前,我们需要深入剖析 BOSS 直聘搜索结果页的结构,为后续精准抓取数据奠定基础。当我们在 BOSS 直聘官网输入关键词并搜索后,通过浏览器的开发者工具(一般按 F12 调出)查看页面源代码,通过观察和搜索我们发现职位信息是通过 joblist 接口获得的,其数据格式是json,“https://www.zhipin.com/wapi/zpgeek/search/joblist.json?scene=1&query=python&city=101110100&page=1&pageSize=10仔细观察 joblist 接口的 URL,不难发现其中蕴含的规律,如职位关键词、城市代码、页码等参数信息。
那么我直接请求 joblist 接口获取数据。
3.2 网页请求
在 Python 的工具库中,requests 库能高效地向目标网站发送 HTTP 请求,帮我们牵线搭桥获取网页内容。不过,BOSS为了维护自身数据的有序访问,设置了一些防护机制,我们得像智慧的访客一样巧妙应对。
首先,合理设置请求头(headers)至关重要,它就像是我们拜访网站时递出的名片,告知对方我们是友好且正常的浏览器访问。模拟常见浏览器的 User-Agent 字段,如 “Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.212 Safari/537.36”,让服务器误以为我们是普通用户操作。同时,Referer 字段也不可忽视,它记录着请求的来源页面,保持其合理性,能避免一些不必要的拦截。最后,如果网站有动态验证的话我们需要设置 Cookie ,可以从自己浏览器访问记录中找到Cookie参数。
import requests
# 模拟浏览器头部信息
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.212 Safari/537.36",
"Referer": "https://www.zhipin.com",
"Cookie": "ab_guid=625f8db8-0c02-4dad-9c84-7baefdce5984; __g=-; Hm_lvt_194df3105ad7148dcf2b98a91b5e727a=1735802049,1735983167; wt2=DplYpTx9H31TyB7W2dEWbRn31z2myvkMwLNLlGcq-X9qAKPX6I4gL9n2C5zktf10iTSMaXOkRkefhK-jL-eb1Jg~~; wbg=0; zp_at=6xq0DNEJoGPgqYt_Fwt3ATFzWjyQBR8yXuyZcrmBJRE~; lastCity=101110100; Hm_lpvt_194df3105ad7148dcf2b98a91b5e727a=1735985838; __zp_stoken__=5a6afw53EgmMiVCJoLHMmJ8KLbMKPwobCiHnCucONw4d3w5DCg2HDksKrw5TDlMKAwq1oclrDkHxdw4XCtsK%2Bw41nxI3DhcSIYMSNw5TEisKtwq5mw4TDicKpxKrEhMKawrDEg8O%2Bw4nCs0lHGBkbGBomIyEmLBseHyQeJB0fJB4aHx0aGEtFxIvCk8SVSU9SSERnYmweYHBwW3FkHm5kXUpUGWgbfFRDS0hKSMOcwoHDisSCw5XCg8ONxIDDk8KGw45LSFJIScOOw4I9P8OIxJI%2Fw486HcOLwqIew4jCmx%2FDiMK7JMOZfGHClMOuw491TEhKw4nFlFVPLlNOSVFJSFNJTz5IKsOYcWHCi8Opw4rCqzlJLlFPSVdISU9JVU5XO0lRNj9PSDlSGxgnIh46XMOUccOLw6tPSQ%3D%3D; bst=V2Q9wiGO39215gXdJqyRsaKyuw7D_Rxw~~|Q9wiGO39215gXdJqyRsaKyuw7D7WxQ~~; __c=1735985167; __l=l=%2Fwww.zhipin.com%2Fweb%2Fgeek%2Fjob%3Fquery%3Dpython%26city%3D101110100&s=3&friend_source=0&s=3&friend_source=0; __a=50678172.1735985167..1735985167.14.1.14.14"}
# 目标URL,以Python职位为例,搜索西安地区,第一页数据,page为页码,city为城市,query为职位,pageSize为页码
url = "https://www.zhipin.com/wapi/zpgeek/search/joblist.json?scene=1&query=python&city=101110100&page=1&pageSize=10"
# 发送get请求,获取响应
response = requests.post(url, headers=headers)
if response.status_code == 200:
html = response.json()
else:
print(f"请求失败,状态码:{response.status_code}")
在这段代码中,我们精心构建了请求头和请求参数,向BOSS的职位数据接口发起 GET 请求,若请求顺利,便能获得网页数据,为后续的数据解析铺就道路。
3.3 网页解析
当我们成功取回 json 数据后,把它当作一个字典进行拆分,提取职位名称、薪资、公司名称等信息的代码如下:
# 这义列表存储职位信息
job_list = []
# 从json格式的html中取出职位列表
jobList = html["zpData"]["jobList"]
# 循环列表
for job in jobList:
# 获取每个典中的职位信息
job_title = job["jobName"]
salary = job["salaryDesc"]
company_name = job["brandName"]
areaDistrict = job["areaDistrict"]
# 将获得的职位信息填加到临时列表中
jobList.append({"job_title": job_title, "salary": salary, "company_name": company_name, "areaDistrict": areaDistrict})
print(job_title, salary, company_name, areaDistrict)
在这段代码里,我们先定义了列表用于临时存储职位信息,接着提取名称、薪资、公司名称、位置等关键信息,将其清晰呈现。
3.4 保存数据
辛苦抓取并解析得到的数据,需要妥善保存才能让其价值延续。常见的 CSV、JSON 等格式,各有千秋。
CSV 格式,以其简洁的表格形式,通用性强,能被 Excel 等众多软件直接打开编辑,方便数据的初步查看与简单分析。Python 内置的 csv 模块便能担此大任。以下是将获取到的数据保存为 CSV 文件的示例:
import csv
# CSV文件路径
csv_file_path = "zhiping_jobs.csv"
# 写入CSV文件
with open(csv_file_path, 'w', newline='', encoding='utf-8') as csvfile:
fieldnames = ['job_title', 'salary', 'company_name', 'areaDistrict'] # 定义列名
writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
writer.writeheader() # 写入表头
writer.writerows(job_list) # 写入数据行
print(f"数据已成功保存至 {csv_file_path}")
在这段示例中,我们首先定义了 CSV 文件路径,运用 csv.DictWriter 以字典形式将数据逐行写入 CSV 文件,同时写入表头,确保数据存储的规范性与完整性,方便后续随时调取分析。
最后对代码进行整理优化,并增加多页处理。
import requests
import csv
def get_html(url):
# 模拟浏览器头部信息
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.212 Safari/537.36",
"Referer": "https://www.zhipin.com",
"Cookie": "ab_guid=625f8db8-0c02-4dad-9c84-7baefdce5984; __g=-; Hm_lvt_194df3105ad7148dcf2b98a91b5e727a=1735802049,1735983167; wt2=DplYpTx9H31TyB7W2dEWbRn31z2myvkMwLNLlGcq-X9qAKPX6I4gL9n2C5zktf10iTSMaXOkRkefhK-jL-eb1Jg~~; wbg=0; zp_at=6xq0DNEJoGPgqYt_Fwt3ATFzWjyQBR8yXuyZcrmBJRE~; lastCity=101110100; Hm_lpvt_194df3105ad7148dcf2b98a91b5e727a=1735985838; __zp_stoken__=5a6afw53DuHsjXCV0IHIeLMKPYMKOfsKLfcK9w4jCv3zDnMKHbMOKwqjDiMOIwoXCtWt2w4%2FDkWbCv3vDg3LDhcKHwqt2wq3CtsK5WcO6wqnCscOLxJLCs8K0xLLDv8KexI3CoMSIw47CsE1GIB4fJBseICUiISMZGxgfLBobGB8iJBkeHVNCxI%2FCl8SQUVRWVDlfZWAaZWhzX3VZJmlYWUtcHnQfcVxAT1RLUMOXwoXDjsSDw43CgMOJxIzDkn7DiU9UU1BOw4rDhjhHw4vEljvDjkIaw4%2FCph%2FDkMKYG8OUwrosw55wZcKMxJPDicO5R01Sw47FiFFONlBKTVxRS1dNTkZLQsOkfFnChcSLRj5QK1JNTkpJSk1OVEtQOU5IGjhNS0BXJB4sHxs5UsOPaMOOw7RNTg%3D%3D; bst=V2Q9wiGO39215gXdJqyRsaKyuw7DPVzQ~~|Q9wiGO39215gXdJqyRsaKyuw7DnQxg~~; __c=1735985167; __l=l=%2Fwww.zhipin.com%2Fweb%2Fgeek%2Fjob%3Fquery%3Dpython%26city%3D101110100&s=3&friend_source=0&s=3&friend_source=0; __a=50678172.1735985167..1735985167.23.1.23.23"}
# 目标URL,以Python职位为例,搜索西安地区,第一页数据,page为页码,city为城市,query为职位,pageSize为页码
url = "https://www.zhipin.com/wapi/zpgeek/search/joblist.json?scene=1&query=python&city=101110100&page=1&pageSize=10"
# 发送get请求,获取响应
response = requests.post(url, headers=headers)
if response.status_code == 200:
html = response.json()
else:
print(f"请求失败,状态码:{response.status_code}")
return html
def get_alljobs(html):
# 这义列表存储职位信息
list = []
# 从json格式的html中取出职位列表
jobList = html["zpData"]["jobList"]
# 循环列表
for job in jobList:
# 获取每个典中的职位信息
job_title = job['jobName']
salary = job["salaryDesc"]
company_name = job["brandName"]
areaDistrict = job["areaDistrict"]
# 将获得的职位信息填加到临时列表中
list.append({"job_title": job_title, "salary": salary, "company_name": company_name, "areaDistrict": areaDistrict})
return list
def save_to_csv(jobs):
# CSV文件路径
csv_file_path = "zhiping_jobs.csv"
# 写入CSV文件
with open(csv_file_path, 'w', newline='', encoding='utf-8') as csvfile:
fieldnames = ['job_title', 'salary', 'company_name', 'areaDistrict'] # 定义列名
writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
writer.writeheader() # 写入表头
writer.writerows(jobs) # 写入数据行
return f"数据已成功保存至 {csv_file_path}"
if __name__ == "__main__":
# 目标URL,以Python职位为例,搜索西安地区,第一页数据,page为页码,city为城市,query为职位,pageSize为页码
base_url = "https://www.zhipin.com/wapi/zpgeek/search/joblist.json?scene=1&query=python&city=101110100&pageSize=10"
# 配置页码数量
pages = 3
# 定义一个空列表,存储所有的职位
jobs = []
for i in range(1, pages+1):
url = f"{base_url}&page={i}"
html = get_html(url)
job_list = get_alljobs(html)
jobs.extend(job_list)
print(job_list)
save_to_csv(jobs)
print("爬取完成,数据已保存至 lagou_jobs.csv")
总结
通过本次实战,我们成功运用 Python 爬虫技术从 BOSS 直聘网获取了关键招聘职位信息。从最初精准锚定实战目标,到细致剖析网页结构、巧妙突破网页请求限制、精准解析网页数据,再到妥善保存数据,每一步都环环相扣,为数据的成功抓取奠定基石。
不过,在爬虫实践中,务必严守法律红线与网站规则,尊重网站的 robots.txt 协议,未经授权大规模抓取、过度频繁访问等违规行为,不仅可能触犯法律,还会对网站正常运营造成冲击。建议在爬取数据前,仔细研读网站的使用条款,对于大规模商用数据需求,积极与网站运营方沟通获取授权。
作者:西攻城狮北