概要
今天(2023/3/7)将教大家怎么对百度招聘的社会招聘进行爬取,难度适中,内容包括:岗位名称,岗位类型,招聘人数,工作要求,工作地点等待。
一、使用模块
import csv
import json
import requests
二、反爬技术
1.禁止调试
反爬虫工程师通过js代码禁止用户使用开发者工具
2.动态网页
动态网站通过JavaScript异步加载数据,需要查找数据接口,并且请求参数通常被加密参数保护。
三、分析过程
1.打开网页后,发现下一页的请求方式是通过分页实现。考虑到需要频繁更新数据,这种情况通常不会是静态网页(第一页可能仅用于混淆)。因此,我猜测数据可能存储在 JSON 格式中,通过 JavaScript 动态请求后更新到网页中。
2.右键单击空白处并打开检查面板,结果却跳转到名为“about:blank”的空白页。这是反爬虫措施,通常是通过 JavaScript 脚本禁止用户进行调试。
3.选择“源代码”选项卡,点击事件侦听器断点,并勾选“脚本”,这样页面执行脚本时将进入调试模式。
4.回退网页或重新搜索,现在可以进行调试。接下来,需找到页面重定向的 JavaScript 代码。
5.使用 Ctrl+F 打开代码匹配框,以“about:blank”作为关键词进行搜索。如果没有找到,再执行下一步。
6.当执行到 Page.4d03da52.chunk.js
时,成功匹配到相关代码。点击向下箭头定位到所在行,对 JavaScript 了解不深的可以复制给 AI 帮助解析。这里的核心代码是 window.location.href = "about:blank"
,需要删除这段跳转代码,但直接修改代码是临时的,刷新后将失效。
7.在需要修改的文件名上右键单击,选择“替换内容”。
8.点击“选择文件夹”。
8.选择一个文件夹,或新建一个文件夹。
9.授予获取权限,此时文件将被替换为本地版本,现在可以自由修改代码。
10.删除跳转代码或整个函数。
11.修改完成后,需保存(Ctrl+S)。
12.去除脚本监听断点,释放调试,让代码完全执行。
13.转到“网络”选项卡,点击第二页,并以岗位名作为关键词进行搜索,发现数据以 JSON 格式返回
14.简单分析请求的 URL,发起的是 POST 请求,包含五个参数,其中 curPage
表示页码
四、完整代码
import csv
import json
import requests
def get_datas(curPage):
url = 'https://talent.baidu.com/httservice/getPostListNew'
data = {
'recruitType': 'SOCIAL',
'pageSize': 10,
'keyWord': '',
'curPage': curPage,
'projectType': ''
}
headers = {
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36 Edg/131.0.0.0',
'referer': 'https://talent.baidu.com/jobs/social-list'
}
response = requests.post(url, data=data, headers=headers)
response.raise_for_status() # 将 assert 替换为异常处理
return response.text
def parse_datas(datas):
data_list = []
datas = json.loads(datas)['data']
for data in datas['list']:
job_info = {
'name': data['name'],
'postType': data['postType'],
'publishDate': data['publishDate'],
'recruitNum': data['recruitNum'],
'serviceCondition': data['serviceCondition'],
'workContent': data['workContent'],
'workPlace': data['workPlace']
}
data_list.append(job_info)
return data_list
def save_to_csv(data_list, filename):
keys = data_list[0].keys() # 获取字典的键作为CSV的列名
with open(filename, 'w', newline='', encoding='utf-8') as output_file:
dict_writer = csv.DictWriter(output_file, fieldnames=keys)
dict_writer.writeheader()
dict_writer.writerows(data_list)
if __name__ == '__main__':
all_jobs = []
for page in range(1, 162):
print(f'第{page}页')
datas = get_datas(page)
jobs = parse_datas(datas)
all_jobs.extend(jobs)
save_to_csv(all_jobs, 'job_list.csv')
print(f'共保存 {len(all_jobs)} 条职位信息到 job_list.csv')
小结
今天的内容难度适中,适合新手js逆向入门。