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 协议,未经授权大规模抓取、过度频繁访问等违规行为,不仅可能触犯法律,还会对网站正常运营造成冲击。建议在爬取数据前,仔细研读网站的使用条款,对于大规模商用数据需求,积极与网站运营方沟通获取授权。

作者:西攻城狮北

物联沃分享整理
物联沃-IOTWORD物联网 » Python 爬虫实战案例 – 获取BOSS直聘网招聘职位信息

发表回复