昨天一个朋友说最近想换工做。想让我帮看下Boss如今的招聘状况如何。正好想到上个月写了个开源爬虫框架kcrawler
,最后添加了一个Boss
类支持,能够实现快速根据关键词查询不一样岗位,不一样行业的的招聘状况。有现成可用的库,帮助朋友也是举手之劳。html
1. 安装
kcrawler
是开源的。开发同窗能够选择clone
源码。可是若是想省事,就直接pip install
,而后导入项目使用便可。python
pip install kcrawler
2. 使用
提供两个类。git
-
Crawler: 简单配置爬取任意网站 -
Boss: Boss专用(本文推荐)
2.1 爬虫基类 Crawler
kcrawler
提供了一个爬虫基类 Crawler
, 它封装了一个通用型爬虫的基础功能。经过传入配置字典来实例化一个网站的crawler
对象,而后调用对象的crawler
方法,便可实现指定目标数据的爬取。支持html,json,图像的爬取。如下为Boss
的配置示例。github
def queryjobpage_url(x): p = list() if x[0]: p.append('i' + str(x[0])) if x[1]: p.append('c' + str(x[1])) if x[2]: p.append('p' + str(x[2])) return 'https://www.zhipin.com/{}/'.format('-'.join(p))
config = { 'targets': { 'city': { 'url': 'https://www.zhipin.com/wapi/zpCommon/data/city.json', 'method': 'get', 'type': 'json' }, 'position': { 'url': 'https://www.zhipin.com/wapi/zpCommon/data/position.json', 'method': 'get', 'type': 'json' }, 'industry': { 'url': 'https://www.zhipin.com/wapi/zpCommon/data/oldindustry.json', 'method': 'get', 'type': 'json' }, 'conditions': { 'url': 'https://www.zhipin.com/wapi/zpgeek/recommend/conditions.json', 'method': 'get', 'type': 'json' }, 'job': { 'url': 'https://www.zhipin.com/wapi/zpgeek/recommend/job/list.json', 'method': 'get', 'type': 'json' }, 'queryjob': { 'url': 'https://www.zhipin.com/job_detail/', 'method': 'get', 'type': 'html' }, 'queryjobpage': { 'url': queryjobpage_url, 'method': 'get', 'type': 'html' }, 'jobcard': { 'url': 'https://www.zhipin.com/wapi/zpgeek/view/job/card.json', 'method': 'get', 'type': 'json' } }}
crawler = Crawler(config)
如今完成了爬虫对象的建立。有过爬虫经验的同窗可能已经注意到了,怎么没有headers
?事实上,有两种方法传入headers
。一种是直接在配置字典config
增长headers
键值。例如:web
在浏览器里整个复制Request Headers
,以文档字符串的形式赋值给变量headers
。算法
headers = ''':authority: www.zhipin.com:method: GET:path: /....cookie: xxx....user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.70 Safari/537.36'''config = {'headers': headers, 'targets': { ... }}
第二种推荐的方式是在当前目前下新建一个文件名为headers
的文件。以一样的方法在浏览器复制整个headers
字符串覆盖这个文件,直接覆盖,不用加文档字符变量。当config
字典没有提供headers
字段时,Crawler
会自动从headers
文件读取headers
字符串。json
完成以上步骤,便可调用crawler.crawl(target)
方法爬取数据了。其中target
是配置字典config
中targets
定义的键。api
data = crawler.crawl('job')
2.2 Boss 类
使用Crawler
爬取的数据是网站的原始数据的,虽然已经转换成字典或者列表,可是要进一步获得感兴趣的字段,还须要本身提取。可是kcrawler
已经提供了一个Boss
类能够直接使用。浏览器
固然仍是建议你先按照前文的方法先在浏览器中复制Request Headers
,保存到当前目录下的headers
文件中。而后就能够愉快地使用Boss
类实例化一个对象,爬取感兴趣的数据。微信
from kcrawler import Boss
boss = Boss()
看到以下输出,表示成功读取到headers
文件的内容。
read heades from file.parse headers
2.2.1 招聘城市
cities = boss.city()
返回:
[{'id': 101010000, 'name': '北京', 'pinyin': None, 'firstChar': 'b', 'rank': 1, 'children': [{'id': 101010100, 'name': '北京', 'pinyin': 'beijing', 'firstChar': 'b', 'rank': 1}]}, {'id': 101020000, 'name': '上海',...]
2.2.2 热门城市
hotcities = boss.hotcity()
返回:
[{'id': 100010000, 'name': '全国'}, {'id': 101010100, 'name': '北京'}, {'id': 101020100, 'name': '上海'}, {'id': 101280100, 'name': '广州'}, {'id': 101280600, 'name': '深圳'}, {'id': 101210100, 'name': '杭州'},...]
2.2.3 当前登录用户所在城市
user_city = boss.userCity()
返回:
嘿嘿,就不告诉你。。。
2.2.4 行业
industries = boss.industry()
返回:
[{'id': 100001, 'name': '电子商务'}, {'id': 100002, 'name': '游戏'}, {'id': 100003, 'name': '媒体'}, {'id': 100004, 'name': '广告营销'}, {'id': 100005, 'name': '数据服务'}, {'id': 100006, 'name': '医疗健康'}, {'id': 100007, 'name': '生活服务'}, {'id': 100008, 'name': 'O2O'}, {'id': 100009, 'name': '旅游'}, {'id': 100010, 'name': '分类信息'}, {'id': 100011, 'name': '音乐/视频/阅读'}, {'id': 100012, 'name': '在线教育'}, {'id': 100013, 'name': '社交网络'},...]
2.2.5 当前登录用户指望岗位(三个)
expects = boss.expect()
返回:
[{'id': xxx, 'positionName': 'xxx'}, {'id': xxx, 'positionName': 'xxx'}, {'id': xxx, 'positionName': 'xxx'}]
2.4.6 给当前登录用户推荐的岗位列表
boss.job(i, page)
方法须要提供两个参数,第一个是boss.expect()
返回列表的索引,例如0表明第一个指望岗位的推荐岗位;第二个参数page
用于指定数据分页,例如1是第一页。
jobs = boss.job(0, 1)
返回:
[{'id': 'be8bfdcdf7e99df90XV-0t-8FVo~', 'jobName': '深度学习平台经理/技术中级', 'salaryDesc': '30-50K', 'jobLabels': ['深圳 福田区 购物公园', '5-10年', '本科'], 'brandName': '中国平安', 'brandIndustry': '互联网金融', 'lid': '411f6b88-8a83-437a-aa5f-5de0fc4da2b7.190-GroupC,194-GroupB.1'}, {'id': 'f649c225a1b9038f0nZ609W5E1o~', 'jobName': '推荐系统评测工程师', 'salaryDesc': '20-35K', 'jobLabels': ['深圳 南山区 科技园', '1-3年', '本科'], 'brandName': '腾讯', 'brandIndustry': '互联网', {'id': '94cfec046b98b9671H150tS8E1M~', 'jobName': '用户数据挖掘工程师', 'salaryDesc': '20-40K·15薪', 'jobLabels': ['深圳 南山区 南山中心', '经验不限', '本科'], 'brandName': '今日头条', 'brandIndustry': '移动互联网', 'lid': '411f6b88-8a83-437a-aa5f-5de0fc4da2b7.190-GroupC,194-GroupB.4'},...]
2.4.7 经过关键词搜索岗位
city
, industry
, position
是上文已经爬取的数据对应ID字段;query
不用说就是查询关键词;这里之因此使用两个不一样的方法,由于Boss
搜索岗位第一页和第二页及以后的页面的URL组成结构不一样,前者固定不变,后者是变化的。这也是为何前文传入配置字典的URL使用了函数形式。
所以,若是你只对查询第一页数据感兴趣就使用queryjob
方法;若是你想继续查看第二页及之后的数据,就必须使用queryjobpage
方法。固然,事实上queryjobpage
的方法也能够爬第一页的数据,可是建议分开使用,这样较不容易触发反爬虫机制。毕竟这是用户正常访问时行为。
tencent_jobs1 = boss.queryjob(query='腾讯', city=101280600, industry=None, position=101301)tencent_jobs2 = boss.queryjobpage(query='腾讯', city=101280600, industry=None, position=101301, page=2)
返回:
[{'jobName': '天衍实验室-大数据及人工智能高级研究员', 'salaryDesc': '30-60K', 'jobLabels': ['深圳 南山区 科技园', '3-5年', '硕士'], 'brandName': '腾讯', 'brandIndustry': '互联网', 'id': 'ce6f957a5e4cb3100nZ43dm6ElU~', 'lid': '22Uetj173Sz.search.1'}, {'jobName': 'QQ信息流推荐算法工程师/研究员', 'salaryDesc': '20-40K·14薪', 'jobLabels': ['深圳 南山区 科技园', '经验不限', '本科'], 'brandName': '腾讯', 'brandIndustry': '互联网', 'id': 'a280e0b17a2aeded03Fz3dq_GFQ~', 'lid': '22Uetj173Sz.search.2'},...
github
https://github.com/kenblikylee/kcrawler
本文分享自微信公众号 - 我是一条小青蛇(ws1txqs)。
若有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一块儿分享。