Python爬虫小例子——爬取51job发布的工作职位


Posted in Python onJuly 10, 2020

概述

不知从何时起,Python和爬虫就如初恋一般,情不知所起,一往而深,相信很多朋友学习Python,都是从爬虫开始,其实究其原因,不外两方面:其一Python对爬虫的支持度比较好,类库众多。其二Pyhton的语法简单,入门容易。所以两者形影相随,不离不弃,本文主要以一个简单的小例子,简述Python在爬虫方面的简单应用,仅供学习分享使用,如有不足之处,还请指正。

涉及知识点

本例主要爬取51job发布的工作职位,用到的知识点如下:

  • 开发环境及工具:主要用到Python3.7 ,IDE为PyCharm
  • requests类库:本类库封装了python的内置模块,主要用于网络的请求和获取数据,可以支持不同形式的请求。
  • BeautifulSoup库:主要用于解析获取的数据,包括Html,Xml,Json等不同的格式。
  • 数据持久化:主要是将内存中的数据,保存到数据库或者文件中。

爬虫的基本步骤

爬虫的基本步骤,如下图所示:

Python爬虫小例子——爬取51job发布的工作职位

爬取目标

如有要爬取相关内容,首先要对爬取的目标进行分析,了解其目录结构,才能进行解析。本例主要爬取51job中的工作列表,如下所示:

Python爬虫小例子——爬取51job发布的工作职位

核心源码

1.获取数据

定义一个函数get_data,用于发起请求并获取数据,如下所示:

headers中的User-Agent主要用于模拟浏览器,不然会被反爬虫程序屏蔽,http状态码为418,意思是被网站的反爬程序返回的。

encoding是要爬取的网站的编码为gbk,如果不加,会产生乱码,默认为utf-8

def get_data(req_url):
  """获取数据"""
  headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko',
    'Accept-Language': 'zh-Hans-CN, zh-Hans;q=0.5'
  }
  resp = requests.get(req_url, headers=headers)
  resp.encoding = 'gbk' # 不加会产生中文乱码
  if resp.status_code == 200:
    return resp.text
  else:
    return None

2.解析数据

定义一个函数parse_data,用于解析获取到的内容,如下所示:

采用BeautifulSoup,将返回的文本,解析成html对象,并获取对应的内容。本例主要获取工作的列表

def parse_data(resp_html):
  """解析数据,并返回列表"""
  soup = BeautifulSoup(resp_html, features='html.parser')
  job_table = soup.find('div', attrs={'class': 'dw_table'})
  # print(job_table)
  job_list = job_table.find_all('div', attrs={'class': 'el'})
  # print(job_list)
  # 循环列表,去掉第一个title和最后一个
  res_list = []
  for job in job_list[1: -1]:
    job_name = job.find('p', attrs={'class': "t1"}).find('span').find('a').get_text()
    job_name = job_name.replace('\r\n', '').strip()
    job_company = job.find('span', attrs={'class': "t2"}).find('a').get_text()
    job_addr = job.find('span', attrs={'class': "t3"}).get_text()
    job_salary = job.find('span', attrs={'class': "t4"}).get_text()
    job_time = job.find('span', attrs={'class': "t5"}).get_text()
    # print('工作信息:', job_name, '---', job_company, '---', job_addr, '---', job_salary, '---', job_time)
    res_item = {
      '工作名称': job_name,
      '公司': job_company,
      '工作地址': job_addr,
      '薪资水平': job_salary,
      '发布时间': job_time
    }
    res_list.append(res_item)
  return res_list

3.保存数据

定义一个函数save_data,用于将获取到的内容保存到json文件中,如下所示:

with函数 可以自动进行释放。因包含中文,所以json文件的编码为utf-8,否则会出现乱码

def save_data(res_list):
   """保存数据"""
   with open('jobs.json', 'w', encoding='utf-8') as f:
     res_list_json = json.dumps(res_list, ensure_ascii=False)
     f.write(res_list_json)

4.整体调用步骤

依次调用定义的三个函数,如下所示:

if __name__ == '__main__':
  """如果是主程序自己调用"""
  req_url = 'https://search.51job.com/list/040000,000000,0000,00,9,99,java,2,1.html?lang=c&stype=1&postchannel=0000&workyear=99&cotype=99°reefrom=99&jobterm=99&companysize=99&lonlat=0%2C0&radius=-1&ord_field=0&confirmdate=9&fromType=&dibiaoid=0&address=&line=&specialarea=00&from=&welfare='
  # 获取数据
  resp_html = get_data(req_url)
  # print(html)
  # 解析数据
  res_list = parse_data(resp_html)
  # 保存数据
  save_data(res_list)

爬取结果展示

爬取的结果保存在jobs.json文件中,如下所示:

[
 {
  "工作名称": "Java架构师",
  "公司": "深圳市钻木信息技术有限公司",
  "工作地址": "深圳-福田区",
  "薪资水平": "1.8-3万/月",
  "发布时间": "06-13"
 },
 {
  "工作名称": "Java实习生 6k起",
  "公司": "深圳市智玩创新科技有限公司",
  "工作地址": "深圳-福田区",
  "薪资水平": "6-8千/月",
  "发布时间": "06-13"
 },
 {
  "工作名称": "Java实习生6k起",
  "公司": "深圳市康姆达科技有限公司",
  "工作地址": "深圳-南山区",
  "薪资水平": "6-8千/月",
  "发布时间": "06-13"
 },
 {
  "工作名称": "Java开发工程师",
  "公司": "深圳市网新新思软件有限公司",
  "工作地址": "深圳-南山区",
  "薪资水平": "1.5-1.7万/月",
  "发布时间": "06-13"
 },
 {
  "工作名称": "Java开发工程师",
  "公司": "深圳市睿服科技有限公司",
  "工作地址": "深圳-福田区",
  "薪资水平": "1.3-1.7万/月",
  "发布时间": "06-13"
 },
 {
  "工作名称": "Java开发经理",
  "公司": "深圳市聚惠企业登记代理有限公司",
  "工作地址": "深圳-龙华新区",
  "薪资水平": "1-3万/月",
  "发布时间": "06-13"
 },
 {
  "工作名称": "高级JAVA",
  "公司": "深圳易加油信息科技有限公司",
  "工作地址": "深圳-南山区",
  "薪资水平": "1.5-2.1万/月",
  "发布时间": "06-13"
 },
 {
  "工作名称": "Java高级开发工程师",
  "公司": "深圳市绿联科技有限公司",
  "工作地址": "深圳-龙华新区",
  "薪资水平": "2-3万/月",
  "发布时间": "06-13"
 },
 {
  "工作名称": "Java开发工程师",
  "公司": "深圳市博悦科创科技有限公司",
  "工作地址": "深圳-南山区",
  "薪资水平": "1-1.5万/月",
  "发布时间": "06-13"
 },
 {
  "工作名称": "Java高级开发工程师",
  "公司": "易普森智慧健康科技(深圳)有限公...",
  "工作地址": "深圳",
  "薪资水平": "1.5-2.5万/月",
  "发布时间": "06-13"
 },
 {
  "工作名称": "Java开发工程师",
  "公司": "深圳易世通达科技有限公司",
  "工作地址": "深圳-南山区",
  "薪资水平": "1.2-1.8万/月",
  "发布时间": "06-13"
 },
 {
  "工作名称": "Java开发工程师",
  "公司": "苏州今融加科技有限公司",
  "工作地址": "深圳-福田区",
  "薪资水平": "1.5-2万/月",
  "发布时间": "06-13"
 },
 {
  "工作名称": "Java后端开发工程师",
  "公司": "深圳市长隆科技有限公司",
  "工作地址": "深圳-龙岗区",
  "薪资水平": "1.5-2万/月",
  "发布时间": "06-13"
 },
 {
  "工作名称": "Java开发工程师",
  "公司": "深圳市元诺智能系统有限公司",
  "工作地址": "深圳-龙华新区",
  "薪资水平": "1-1.5万/月",
  "发布时间": "06-13"
 },
 {
  "工作名称": "java 有物流类经验",
  "公司": "深圳市欧恩德技术有限公司",
  "工作地址": "深圳-罗湖区",
  "薪资水平": "0.8-1.1万/月",
  "发布时间": "06-13"
 },
 {
  "工作名称": "Java开发工程师-2020校园招聘",
  "公司": "金蝶软件(中国)有限公司",
  "工作地址": "深圳-南山区",
  "薪资水平": "0.8-1.6万/月",
  "发布时间": "06-13"
 },
 {
  "工作名称": "Java高级开发工程师",
  "公司": "丰疆智能科技股份有限公司",
  "工作地址": "深圳-南山区",
  "薪资水平": "2.5-3万/月",
  "发布时间": "06-13"
 },
 {
  "工作名称": "JAVA软件开发工程师",
  "公司": "深圳市吉星时代科技有限公司",
  "工作地址": "深圳-龙岗区",
  "薪资水平": "2-3万/月",
  "发布时间": "06-13"
 },
 {
  "工作名称": "JAVA 高级软件工程师",
  "公司": "相通网络技术有限公司",
  "工作地址": "深圳-福田区",
  "薪资水平": "1.5-3万/月",
  "发布时间": "06-13"
 },
 {
  "工作名称": "JAVA开发工程师(接受应届生)",
  "公司": "深圳市智岩科技有限公司",
  "工作地址": "深圳-南山区",
  "薪资水平": "0.8-1万/月",
  "发布时间": "06-13"
 },
 {
  "工作名称": "Java后台开发工程师",
  "公司": "深圳市炬驰科技发展有限公司",
  "工作地址": "深圳",
  "薪资水平": "1-1.5万/月",
  "发布时间": "06-13"
 },
 {
  "工作名称": "Java开发工程师",
  "公司": "深圳市韶音科技有限公司",
  "工作地址": "深圳-宝安区",
  "薪资水平": "0.8-1万/月",
  "发布时间": "06-13"
 },
 {
  "工作名称": "JAVA 开发工程师",
  "公司": "深圳市优博讯科技股份有限公司",
  "工作地址": "深圳-南山区",
  "薪资水平": "1-1.5万/月",
  "发布时间": "06-13"
 },
 {
  "工作名称": "Java开发工程师",
  "公司": "深圳市有豆科技有限公司",
  "工作地址": "深圳-宝安区",
  "薪资水平": "1.8-3万/月",
  "发布时间": "06-13"
 },
 {
  "工作名称": "Saas平台架构师(Java方向)",
  "公司": "深圳市智布互联纺织科技有限公司",
  "工作地址": "深圳-南山区",
  "薪资水平": "1.7-2.5万/月",
  "发布时间": "06-13"
 },
 {
  "工作名称": "Java开发实习生",
  "公司": "云软科技",
  "工作地址": "深圳-宝安区",
  "薪资水平": "6-9千/月",
  "发布时间": "06-13"
 },
 {
  "工作名称": "Java高级开发工程师",
  "公司": "深圳市阿尔法智汇科技有限公司",
  "工作地址": "深圳-宝安区",
  "薪资水平": "2-4万/月",
  "发布时间": "06-13"
 },
 {
  "工作名称": "Java 全栈开发工程师",
  "公司": "深圳市杰纳斯科技有限公司",
  "工作地址": "深圳-宝安区",
  "薪资水平": "1-3.5万/月",
  "发布时间": "06-13"
 },
 {
  "工作名称": "中高级java工程师",
  "公司": "北京联创智融信息技术有限公司",
  "工作地址": "深圳-福田区",
  "薪资水平": "1.3-1.8万/月",
  "发布时间": "06-13"
 },
 {
  "工作名称": "Java开发工程师",
  "公司": "得实信息科技(深圳)有限公司",
  "工作地址": "深圳-南山区",
  "薪资水平": "0.6-1万/月",
  "发布时间": "06-13"
 },
 {
  "工作名称": "Java开发工程师",
  "公司": "深圳市联创科技集团有限公司",
  "工作地址": "深圳-龙岗区",
  "薪资水平": "1-1.5万/月",
  "发布时间": "06-13"
 },
 {
  "工作名称": "中级JAVA(J13824)",
  "公司": "银雁科技服务集团股份有限公司",
  "工作地址": "深圳-福田区",
  "薪资水平": "1-1.5万/月",
  "发布时间": "06-13"
 },
 {
  "工作名称": "java工程师",
  "公司": "深圳市安思疆科技有限公司",
  "工作地址": "深圳-南山区",
  "薪资水平": "0.8-1.6万/月",
  "发布时间": "06-13"
 },
 {
  "工作名称": "JAVA 高级开发工程师",
  "公司": "汇才保险代理(深圳)有限公司",
  "工作地址": "深圳-罗湖区",
  "薪资水平": "1.5-2万/月",
  "发布时间": "06-13"
 },
 {
  "工作名称": "Java高级开发工程师(直连)",
  "公司": "深圳市天泰国际航空旅行社有限公司...",
  "工作地址": "深圳",
  "薪资水平": "2-4万/月",
  "发布时间": "06-13"
 },
 {
  "工作名称": "JAVA工程师",
  "公司": "深圳市开度贸易有限公司",
  "工作地址": "深圳-南山区",
  "薪资水平": "0.8-1.2万/月",
  "发布时间": "06-13"
 },
 {
  "工作名称": "后台开发Leader(JAVA方向)",
  "公司": "深圳金世纪保险经纪有限公司",
  "工作地址": "深圳-福田区",
  "薪资水平": "3-4万/月",
  "发布时间": "06-13"
 },
 {
  "工作名称": "Java开发工程师",
  "公司": "深圳市中深力人力资源管理有限公司...",
  "工作地址": "深圳-南山区",
  "薪资水平": "1-1.5万/月",
  "发布时间": "06-13"
 },
 {
  "工作名称": "Java高级开发工程师",
  "公司": "研祥高科技控股集团有限公司",
  "工作地址": "深圳-光明新区",
  "薪资水平": "0.9-1.8万/月",
  "发布时间": "06-13"
 },
 {
  "工作名称": "Java(证券不加班)",
  "公司": "上海华腾软件系统有限公司",
  "工作地址": "深圳-福田区",
  "薪资水平": "1.8-2.2万/月",
  "发布时间": "06-13"
 },
 {
  "工作名称": "Java高级开发工程师",
  "公司": "深圳大美商业地产管理有限公司",
  "工作地址": "深圳-福田区",
  "薪资水平": "1.5-2万/月",
  "发布时间": "06-13"
 },
 {
  "工作名称": "资深/高级Java工程师",
  "公司": "未来穿戴(深圳)有限公司",
  "工作地址": "深圳-南山区",
  "薪资水平": "3-4万/月",
  "发布时间": "06-13"
 },
 {
  "工作名称": "Java高级开发工程师",
  "公司": "深圳市太阳星通信科技有限公司",
  "工作地址": "深圳-南山区",
  "薪资水平": "0.8-1.5万/月",
  "发布时间": "06-13"
 },
 {
  "工作名称": "Java高级开发工程师",
  "公司": "深圳市蓝鹰立德软件咨询有限公司",
  "工作地址": "深圳-南山区",
  "薪资水平": "1.5-1.8万/月",
  "发布时间": "06-13"
 },
 {
  "工作名称": "JAVA(高级、架构)",
  "公司": "深圳市几米物联有限公司",
  "工作地址": "深圳-宝安区",
  "薪资水平": "2.2-3.2万/月",
  "发布时间": "06-13"
 },
 {
  "工作名称": "JAVA开发工程师",
  "公司": "江苏康尚生物医疗科技有限公司",
  "工作地址": "深圳-宝安区",
  "薪资水平": "1-1.5万/月",
  "发布时间": "06-13"
 },
 {
  "工作名称": "java架构师",
  "公司": "深圳市泓齐网络科技有限公司",
  "工作地址": "深圳",
  "薪资水平": "1.5-1.8万/月",
  "发布时间": "06-13"
 },
 {
  "工作名称": "Java开发工程师",
  "公司": "深圳市智?科技有限公司",
  "工作地址": "深圳-福田区",
  "薪资水平": "0.9-1.5万/月",
  "发布时间": "06-13"
 },
 {
  "工作名称": "Java开发工程师",
  "公司": "上海舟恩信息技术有限公司",
  "工作地址": "深圳-南山区",
  "薪资水平": "1.4-1.9万/月",
  "发布时间": "06-13"
 }
]

进一步思考

本例可以进一步优化的空间,如下所示:

  • 本次爬虫只是单次爬取,数据量相对小,如果要爬取大量数据的时候,则需要使用多线程相关的知识。
  • 基础的爬虫,只能爬取静态渲染的内容,如果是异步动态渲染的数据,如何爬取呢?
  • 将爬取的结果保存到数据库如何操作呢?

以上就是Python爬虫小例子——爬取51job发布的工作职位的详细内容,更多关于Python爬虫爬取工作职位的资料请关注三水点靠木其它相关文章!

Python 相关文章推荐
python使用心得之获得github代码库列表
Jun 25 Python
在Docker上开始部署Python应用的教程
Apr 17 Python
浅谈python中截取字符函数strip,lstrip,rstrip
Jul 17 Python
python如何实现excel数据添加到mongodb
Jul 30 Python
python学生信息管理系统
Mar 13 Python
python实现二维数组的对角线遍历
Mar 02 Python
详解Python二维数组与三维数组切片的方法
Jul 18 Python
Python字符串和正则表达式中的反斜杠('\')问题详解
Sep 03 Python
基于python判断目录或者文件代码实例
Nov 29 Python
Python控制鼠标键盘代码实例
Dec 08 Python
用pip给python安装matplotlib库的详细教程
Feb 24 Python
Django展示可视化图表的多种方式
Apr 08 Python
Python 如何对文件目录操作
Jul 10 #Python
Python下划线5种含义代码实例解析
Jul 10 #Python
Python 没有main函数的原因
Jul 10 #Python
如何教少儿学习Python编程
Jul 10 #Python
Django def clean()函数对表单中的数据进行验证操作
Jul 09 #Python
django form和field具体方法和属性说明
Jul 09 #Python
浅谈Python里面None True False之间的区别
Jul 09 #Python
You might like
php 判断服务器操作系统的类型
2014/02/17 PHP
php5.3 goto函数介绍和示例
2014/03/21 PHP
PHP错误Allowed memory size of 67108864 bytes exhausted的3种解决办法
2014/07/28 PHP
laravel 如何实现引入自己的函数或类库
2019/10/15 PHP
在js文件中如何获取basePath处理js路径问题
2013/07/10 Javascript
JS网页播放声音实现代码兼容各种浏览器
2013/09/22 Javascript
Jquery的each里用return true或false代替break或continue
2014/05/21 Javascript
JavaScript中的数组操作介绍
2014/12/30 Javascript
PHPExcel中的一些常用方法汇总
2015/01/23 Javascript
详解Webwork中Action 调用的方法
2016/02/02 Javascript
JavaScript知识点总结(六)之JavaScript判断变量数据类型
2016/05/31 Javascript
基于jQuery实现照片墙自动播放特效
2017/01/12 Javascript
Bootstrap笔记之缩略图、警告框实例详解
2017/03/09 Javascript
Node.js中的require.resolve方法使用简介
2017/04/23 Javascript
详解Vue如何支持JSX语法
2017/11/10 Javascript
jQuery实现的下雪动画效果示例【附源码下载】
2018/02/02 jQuery
vue router 配置路由的方法
2018/07/26 Javascript
laydate如何根据开始时间或者结束时间限制范围
2018/11/15 Javascript
js函数柯里化的方法和作用实例分析
2020/04/11 Javascript
Python中使用装饰器和元编程实现结构体类实例
2015/01/28 Python
实例讲解Python设计模式编程之工厂方法模式的使用
2016/03/02 Python
Python中import导入上一级目录模块及循环import问题的解决
2016/06/04 Python
Python socket套接字实现C/S模式远程命令执行功能案例
2018/07/06 Python
python训练数据时打乱训练数据与标签的两种方法小结
2018/11/08 Python
Python+OpenCV感兴趣区域ROI提取方法
2019/01/10 Python
不归路系列:Python入门之旅-一定要注意缩进!!!(推荐)
2019/04/16 Python
python3.7 的新特性详解
2019/07/25 Python
python语言的优势是什么
2020/06/17 Python
python支持多继承吗
2020/06/19 Python
戴尔美国官网:Dell
2016/08/31 全球购物
南非最大的花卉和送礼服务:NetFlorist
2017/09/13 全球购物
医学生实习自荐信
2013/10/01 职场文书
学生安全责任书范本
2014/07/24 职场文书
环保志愿者活动方案
2014/08/14 职场文书
珍惜资源的建议书
2014/08/26 职场文书
房屋维修协议书范本
2014/09/25 职场文书