前程无忧最新岗位招聘爬虫简单逆向分析思路-2023.3.1

查看 147|回复 10
作者:xcngg   
51job 招聘岗位爬虫逆向
新人帖,佬勿喷
抓取站点:前程无忧
在线工具: 在线HmacSHA256
最近发现之前写的前程无忧岗位爬虫的代码没法用了,上去看了一眼,好家伙,网页渲染方式果然又又又更新了,之前的岗位数据是直接放在源码里的,现在放在了接口里。
用F12浅浅抓个包,就能很快找到找到接口。


f12接口寻找.png (153.19 KB, 下载次数: 0)
下载附件
2023-3-1 21:15 上传

这个接口是get请求方式,直接请求一下接口,发现鉴权失败,签名错误,昂,果然有反爬措施。


签名错误.png (29.74 KB, 下载次数: 0)
下载附件
2023-3-1 21:15 上传

回去看看接口的请求头部分,熟悉的大佬们一眼就能看出这个sign非常可疑,结合刚刚的错误提示,可以知道,sign就是signature 即签名的缩写。


signature.png (87.61 KB, 下载次数: 0)
下载附件
2023-3-1 21:15 上传

按下Ctrl+Shift+F,搜索下sign。


sign搜索.png (78.09 KB, 下载次数: 0)
下载附件
2023-3-1 21:15 上传

可以看到有一大堆文件包含了sign这个单词,首先排除css文件,这种加密的参数大概率是由js文件生成的。
在搜索出来的js文件中再不断搜索关键词sign,可以看到
return e.headers.sign = p.a.HmacSHA256(t, s["a"].state.commonStore.cupid_sign_key),
这块地方设置了headers.sign属性,并且,这里使用了HmacSHA256加密方式,这和我们需要破解的请求头sign参数是相关联的,所以可以尝试一下,在前面打个断点,再搜索一次其他岗位,看看会不会断住。


sign搜索到关键参数.png (131.76 KB, 下载次数: 0)
下载附件
2023-3-1 21:15 上传

可以看到,我们成功断点断住了。


js控制台参数分析.png (193.11 KB, 下载次数: 0)
下载附件
2023-3-1 21:15 上传

在控制台里看一下加密方法中的参数
t:'/open/noauth/search-pc?api_key=51job×tamp=1677644880&keyword=python%E5%AE%9E%E4%B9%A0%E7%94%9F&searchType=2&function=&industry=&jobArea=000000&jobArea2=&landmark=&metro=&salary=&workYear=°ree=&companyType=&companySize=&jobType=&issueDate=&sortType=0&pageNum=1&requestId=&pageSize=50&source=1&accountId=&pageCode=sou%7Csou%7Csoulb'
s["a"].state.commonStore.cupid_sign_key:'abfc8f9dcf8c3f3d8aa294ac5f2cf2cc7767e5592590f39c3f503271dd68562b'
很明显,t是请求的路径,那么s["a"].state.commonStore.cupid_sign_key 是什么呢?


key是静态.png (62.58 KB, 下载次数: 0)
下载附件
2023-3-1 21:15 上传

我们在这个js文件中查看一下,可以看到,key是静态不变的,就是一个前端写好的加密密钥。
得到这样的结果,我们用在线HmacSHA256加密一下这两个参数,看看和这次请求的sign是否对应


在线hmac256.png (53.44 KB, 下载次数: 0)
下载附件
2023-3-1 21:15 上传

再看看这次请求的参数


sign加密参数.png (35.64 KB, 下载次数: 0)
下载附件
2023-3-1 21:15 上传

没错,一毛一样,基本完工。
这里需要注意的是,每次搜索时,会对当前的关键词进行url编码


url编码.png (119.28 KB, 下载次数: 0)
下载附件
2023-3-1 21:15 上传

可以拿在线工具对比一下。


在线url编码.png (21.33 KB, 下载次数: 0)
下载附件
2023-3-1 21:15 上传

接下来给出Python实现的爬虫代码,这里把数据存储为了csv文件。
import hmac
from hashlib import sha256
import time
import requests
from urllib.parse import quote
import pandas as pd
# 实现 返回 hmac_sha256 算法
def hmac_sha256(key, value):
    message = value.encode('utf-8')
    return hmac.new(key.encode('utf-8'), message, digestmod=sha256).hexdigest()
# 抓取数据
# 参数为需要搜索的招聘信息内容,页码
def get_data(search,page):
    target = "https://cupid.51job.com"
    # hmac_sha256 密钥
    key = "abfc8f9dcf8c3f3d8aa294ac5f2cf2cc7767e5592590f39c3f503271dd68562b"
    # hmac_sha256 加密信息 时间戳 搜索的关键词
    value = f"/open/noauth/search-pc?api_key=51job&timestamp={str(int(time.time()))}&keyword={search}&searchType=2&function=&industry=&jobArea=000000&jobArea2=&landmark=&metro=&salary=&workYear=&degree=&companyType=&companySize=&jobType=&issueDate=&sortType=0&pageNum={page}&requestId=&pageSize=50&source=1&accountId=&pageCode=sou%7Csou%7Csoulb"
    # 请求头
    headers = {
        "sign": hmac_sha256(key, value),
    }
    print("sign:",headers['sign'])
    # 获取响应 json 格式化
    response = requests.get(url=target+value,headers=headers).json()
    return response
# 生成csv
# 参数 csv文件名,csv数据
def generate_csv(file_name,data):
    csv_data = pd.DataFrame(data)
    csv_data.to_csv(f"./{file_name}.csv")
def main():
    #岗位
    search_word = "python实习生"
    # 最后的csv的数据
    result = list()
    # 对关键词进行url编码 否则无法实现中文爬虫
    # 翻页
    for page in range(1,10):
        job_data = get_data(search=quote(search_word), page=page)["resultbody"]['job']["items"]
        print(f"[Success] Crawler Page:{page} | OVER",)
        result += job_data
    # 生成csv
    generate_csv(file_name=search_word, data=result)
    print(f"[Success] Generate-Csv {search_word}.csv | OVER")
if __name__ == "__main__":
    main()
看到评论反馈,发现上传帖子后value的变量值还有一些源码内容会发生改变
所以大家直接参考源码截图吧


code.png (195.46 KB, 下载次数: 0)
下载附件
2023-3-3 16:06 上传

有需要也可以直接下载源码

51jobs.zip
(215.91 KB, 下载次数: 4)
2023-3-3 16:17 上传
点击文件名下载附件
源码下载积分: 吾爱币 -1 CB

运行效果


运行效果.png (45.17 KB, 下载次数: 0)
下载附件
2023-3-1 21:15 上传

csv预览


csv预览.png (59.14 KB, 下载次数: 0)
下载附件
2023-3-1 21:15 上传

下载次数, 下载附件

xcngg
OP
  


小傲宇 发表于 2023-3-3 11:55
报这个错,想了半天没想明白
把vlaue的值修改一下试试看
    value = f"/open/noauth/search-pc?api_key=51job&timestamp={str(int(time.time()))}&keyword={search}&searchType=2&function=&industry=&jobArea=000000&jobArea2=&landmark=&metro=&salary=&workYear=&degree=&companyType=&companySize=&jobType=&issueDate=&sortType=0&pageNum={page}&requestId=&pageSize=50&source=1&accountId=&pageCode=sou%7Csou%7Csoulb"
我的本地源码是这个,但是上传论坛后不知道为什么 timestamp就变了还有一些参数也可能被改变了 详细的可以参考源码图


code.png (195.46 KB, 下载次数: 0)
下载附件
2023-3-3 16:12 上传

xcngg
OP
  


117467746 发表于 2023-3-2 17:17
为什么sign这里我下断点 断不下来 请教

我记得有两个 return e.headers.sign =  p.a.DHmacSHA256(t,s["a"].state.commonstore.cupid_sign_key) 生成的地方 有个地方断点是不执行不生效的,所以可以在存在sign的js文件里ctrl+f 搜索一下sign(会有20左右个结果) 然后找一下另一个相似的地方加上断点尝试一下 哪个执行就是哪个地方是生成加密的地方
或者是断点的地方是正确的 需要在网页内搜索一下不一样的岗位关键词 因为相同的关键词这个网站是不会再次执行搜索的
希望对你有帮助
liuman02   

感谢分享。正适合我这样的小白看。
如果把工具那些网址放上就更完美了。
Asdeo   

有工具安装包就更完美了
lansemeiying   

这个好,回去试试
莫问刀   

感谢分享。正适合我这样的小白看。
cflying   

嗯嗯,不错不错,其实如果爬多了,后面还有个验证页面。
117467746   

为什么sign这里我下断点 断不下来 请教
xcngg
OP
  


cflying 发表于 2023-3-2 10:34
嗯嗯,不错不错,其实如果爬多了,后面还有个验证页面。

是的是的 之前的51是有阿里云盾滑块的 最近这个版本的51可能我脸白好像没有触发过
您需要登录后才可以回帖 登录 | 立即注册

返回顶部