智联招聘爬虫源码分析(一)

简介: 最近一直在关注秋招,虽然还没轮到我,不过提前准备总是好的。近期听闻今年秋招形势严峻,为了更好的准备将来的实习、工作,我决定在招聘网站上爬取一些与数据有关的岗位信息,借以给自己将来的职业道路选择提供参考。
+关注继续查看

    最近一直在关注秋招,虽然还没轮到我,不过提前准备总是好的。近期听闻今年秋招形势严峻,为了更好的准备将来的实习、工作,我决定在招聘网站上爬取一些与数据有关的岗位信息,借以给自己将来的职业道路选择提供参考。

 

一、原理

    通过Python的requests库,向网站服务器发送请求,服务器返回相关网页的源码,再通过正则表达式等方式在网页源码中提取出我们想要的信息。

 

二、网页分析

    2.1岗位详情url

        在智联招聘网站中搜索'大数据',跳转到大数据岗位页面,接下来我们点开开发者选项,刷新页面,在Network面板的XHR中发现了这样一个数据包:

XHR: XHR为向服务器发送请求和解析服务器响应提供了流畅的接口,能够以异步方式从服务器取得更多信息,意味着用户单击后,可以不必刷新页面也能取得新数据

        在新的页面打开后:

        这个页面里出现的所有的岗位信息都在里面了:岗位名称、公司名称、薪水、地区、详情界面的url都在该json里。但是这些信息都不是最重要的,我需要岗位要求以及岗位职责的要求。

        将该json解析,得到如下结构的json数据:

        code的值为HTTP的响应码,200表示请求成功。而results数组则是该页面岗位信息的数据。点开第一条数据(results的第一个元素):

        页面中出现的所有数据,以及相关的超链接都在这儿。其中,我们需要的是指向岗位详情界面的超链接——'positionURL'。点击该链接,进去该岗位信息详情页面:

        好了,我们需要的信息出现了,不过为了简化页面分析的操作,以及尽可能地不被反爬,我决定选择移动适配的页面。

        再打开开发者选项,在该岗位详情页面,刷新:

        在<meta>中找到'mobile-agent',提取后面的url——'url=//m.zhaopin.com/jobs/CZ745244850J00020982209/',打开:

        真清爽!

    2.2 Xpath定位

        XPath即为XML路径语言(XML Path Language),它是一种用来确定XML文档中某部分位置的语言

    分析该网页的源代码,寻找我们所需信息的位置:

    岗位名称、月薪、公司、地区、学历、年限信息都在'//*[@id="r_content"]/div[1]/div/div[1]/div[1]/'下。

  1. title = selector.xpath('//*[@id="r_content"]/div[1]/div/div[1]/div[1]/h1/text()')  
  2. pay = selector.xpath('//*[@id="r_content"]/div[1]/div/div[1]/div[1]/div[1]/text()')  
  3. place = selector.xpath('//*[@id="r_content"]/div[1]/div/div[1]/div[3]/div[1]/span[1]/text()')  
  4. campanyName = selector.xpath('//*[@id="r_content"]/div[1]/div/div[1]/div[2]/text()')  
  5. edu = selector.xpath('//*[@id="r_content"]/div[1]/div/div[1]/div[3]/div[1]/span[3]/text()')  

 

岗位要求与岗位职责在同一个<div>标签里:

    也爬出来:

  1. comment = selector.xpath('//*[@id="r_content"]/div[1]/div/article/div/p/text()')  

好了,最复杂的部分搞定。

 

三、JSON数据包地址

    我们将前三页的数据包地址比对一下就能看出问题:

  1. https://fe-api.zhaopin.com/c/i/sou?pageSize=60&cityId=489&workExperience=-1&education=-1&companyType=-1&employmentType=-1&jobWelfareTag=-1&kw=%E5%A4%A7%E6%95%B0%E6%8D%AE&kt=3&_v=0.14571817&x-zp-page-request-id=ce8cbb93b9ad4372b4a9e3330358fe7c-1541763191318-555474  
  2. https://fe-api.zhaopin.com/c/i/sou?start=60&pageSize=60&cityId=489&workExperience=-1&education=-1&companyType=-1&employmentType=-1&jobWelfareTag=-1&kw=%E5%A4%A7%E6%95%B0%E6%8D%AE&kt=3&_v=0.14571817&x-zp-page-request-id=ce8cbb93b9ad4372b4a9e3330358fe7c-1541763191318-555474  
  3. https://fe-api.zhaopin.com/c/i/sou?start=120&pageSize=60&cityId=489&workExperience=-1&education=-1&companyType=-1&employmentType=-1&jobWelfareTag=-1&kw=%E5%A4%A7%E6%95%B0%E6%8D%AE&kt=3&_v=0.14571817&x-zp-page-request-id=ce8cbb93b9ad4372b4a9e3330358fe7c-1541763191318-555474  
  4. https://fe-api.zhaopin.com/c/i/sou?start=180&pageSize=60&cityId=489&workExperience=-1&education=-1&companyType=-1&employmentType=-1&jobWelfareTag=-1&kw=%E5%A4%A7%E6%95%B0%E6%8D%AE&kt=3&_v=0.14571817&x-zp-page-request-id=ce8cbb93b9ad4372b4a9e3330358fe7c-1541763191318-555474  

1.我们可以看出第一页的url结构与后面的url结构有明显的不同。

2.非首页的url有明显的规律性。

3.'kw=*&kt'里的字符为'大数据'的UTF-8编码。

 

所以我们对数据包有如下的操作:

  1. if __name__ == '__main__':  
  2.     key = '大数据'  
  3.     
  4.     url = 'https://fe-api.zhaopin.com/c/i/sou?pageSize=60&cityId=489&workExperience=-1&education=-1&companyType=-1&employmentType=-1&jobWelfareTag=-1&kw=' + key + '&kt=3&lastUrlQuery=%7B%22pageSize%22:%2260%22,%22jl%22:%22489%22,%22kw%22:%22%E5%A4%A7%E6%95%B0%E6%8D%AE%22,%22kt%22:%223%22%7D'  
  5.     infoUrl(url)  
  6.     
  7.     urls = ['https://fe-api.zhaopin.com/c/i/sou?start={}&pageSize=60&cityId=489&kw='.format(i*60)+key+'&kt=3&lastUrlQuery=%7B%22p%22:{},%22pageSize%22:%2260%22,%22jl%22:%22489%22,%22kw%22:%22java%22,%22kt%22:%223%22%7D'.format(i) for i in range(1,50)]  
  8.     for url in urls:  
  9.         infoUrl(url)  

 

四、源码结构

    1、截取整个结果界面的JSON数据包,从中提取出各个招聘栏的url。

    2、进入招聘详细信息页面,提取移动端url。

    3、进入移动端界面,抓取需要的信息。

 

五、源码

  1. ''''' 
  2.     智联招聘——爬虫源码————2018.11 
  3. '''  
  4. import requests  
  5. import re  
  6. import time  
  7. from lxml import etree  
  8. import csv  
  9. import random  
  10.     
  11. fp = open('智联招聘.csv','wt',newline='',encoding='UTF-8')  
  12. writer = csv.writer(fp)  
  13. '''''地区,公司名,学历,岗位描述,薪资,福利,发布时间,工作经验,链接'''  
  14. writer.writerow(('职位','公司','地区','学历','岗位','薪资','福利','工作经验','链接'))  
  15.     
  16. def info(url):  
  17.     res = requests.get(url)  
  18.     u = re.findall('<meta name="mobile-agent" content="format=html5; url=(.*?)" />', res.text)  
  19.     
  20.     if len(u) > 0:  
  21.         u = u[-1]  
  22.     else:  
  23.         return  
  24.     
  25.     u = 'http:' + u  
  26.     
  27.     headers ={  
  28.         'User-Agent''Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.116 Safari/537.36'  
  29.     }  
  30.     
  31.     res = requests.get(u,headers=headers)  
  32.     selector = etree.HTML(res.text)  
  33.     
  34.     # # 岗位名称  
  35.     title = selector.xpath('//*[@id="r_content"]/div[1]/div/div[1]/div[1]/h1/text()')  
  36.     # # 岗位薪资  
  37.     pay = selector.xpath('//*[@id="r_content"]/div[1]/div/div[1]/div[1]/div[1]/text()')  
  38.     # # 工作地点  
  39.     place = selector.xpath('//*[@id="r_content"]/div[1]/div/div[1]/div[3]/div[1]/span[1]/text()')  
  40.     # # 公司名称  
  41.     companyName = selector.xpath('//*[@id="r_content"]/div[1]/div/div[1]/div[2]/text()')  
  42.     # # 学历  
  43.     edu = selector.xpath('//*[@id="r_content"]/div[1]/div/div[1]/div[3]/div[1]/span[3]/text()')  
  44.     # # 福利  
  45.     walfare = selector.xpath('//*[@id="r_content"]/div[1]/div/div[3]/span/text()')  
  46.     # # 工作经验  
  47.     siteUrl = res.url  
  48.     workEx = selector.xpath('//*[@id="r_content"]/div[1]/div/div[1]/div[3]/div[1]/span[2]/text()')  
  49.     # # 岗位详细  
  50.     comment = selector.xpath('//*[@id="r_content"]/div[1]/div/article/div/p/text()')  
  51.     writer.writerow((title, companyName, place, edu, comment, pay, walfare, workEx, siteUrl))  
  52.     print(title, companyName, place, edu, comment, pay, walfare, workEx, siteUrl)  
  53.     
  54. def infoUrl(url):  
  55.     res = requests.get(url)  
  56.     selector = res.json()  
  57.     code = selector['code']  
  58.     if code == 200:  
  59.         data = selector['data']['results']  
  60.         for i in data:  
  61.             href = i['positionURL']  
  62.             info(href)  
  63.             time.sleep(random.randrange(1,4))  
  64.     
  65. if __name__ == '__main__':  
  66.     key = '大数据'  
  67.     
  68.     url = 'https://fe-api.zhaopin.com/c/i/sou?pageSize=60&cityId=489&workExperience=-1&education=-1&companyType=-1&employmentType=-1&jobWelfareTag=-1&kw=' + key + '&kt=3&lastUrlQuery=%7B%22pageSize%22:%2260%22,%22jl%22:%22489%22,%22kw%22:%22%E5%A4%A7%E6%95%B0%E6%8D%AE%22,%22kt%22:%223%22%7D'  
  69.     infoUrl(url)  
  70.     
  71.     urls = ['https://fe-api.zhaopin.com/c/i/sou?start={}&pageSize=60&cityId=489&kw='.format(i*60)+key+'&kt=3&lastUrlQuery=%7B%22p%22:{},%22pageSize%22:%2260%22,%22jl%22:%22489%22,%22kw%22:%22java%22,%22kt%22:%223%22%7D'.format(i) for i in range(1,50)]  
  72.     for url in urls:  
  73.         infoUrl(url)  

 

Ps.因为某些原因,我打算每个月爬取智联招聘、51job的岗位信息一次,源码、优化都会以博客的形式写出来,欢迎关注~

 

源码地址:智联招聘_爬虫源码

相关实践学习
简单用户画像分析
本场景主要介绍基于海量日志数据进行简单用户画像分析为背景,如何通过使用DataWorks完成数据采集 、加工数据、配置数据质量监控和数据可视化展现等任务。
SaaS 模式云数据仓库必修课
本课程由阿里云开发者社区和阿里云大数据团队共同出品,是SaaS模式云原生数据仓库领导者MaxCompute核心课程。本课程由阿里云资深产品和技术专家们从概念到方法,从场景到实践,体系化的将阿里巴巴飞天大数据平台10多年的经过验证的方法与实践深入浅出的讲给开发者们。帮助大数据开发者快速了解并掌握SaaS模式的云原生的数据仓库,助力开发者学习了解先进的技术栈,并能在实际业务中敏捷的进行大数据分析,赋能企业业务。 通过本课程可以了解SaaS模式云原生数据仓库领导者MaxCompute核心功能及典型适用场景,可应用MaxCompute实现数仓搭建,快速进行大数据分析。适合大数据工程师、大数据分析师 大量数据需要处理、存储和管理,需要搭建数据仓库?学它! 没有足够人员和经验来运维大数据平台,不想自建IDC买机器,需要免运维的大数据平台?会SQL就等于会大数据?学它! 想知道大数据用得对不对,想用更少的钱得到持续演进的数仓能力?获得极致弹性的计算资源和更好的性能,以及持续保护数据安全的生产环境?学它! 想要获得灵活的分析能力,快速洞察数据规律特征?想要兼得数据湖的灵活性与数据仓库的成长性?学它! 出品人:阿里云大数据产品及研发团队专家 产品 MaxCompute 官网 https://www.aliyun.com/product/odps&nbsp;
目录
相关文章
|
6月前
|
数据采集 存储 搜索推荐
搜索引擎爬虫的工作原理是什么?底层原理是什么?
搜索引擎爬虫的工作原理是什么?底层原理是什么?
132 0
|
7月前
|
数据采集 JSON 前端开发
爬虫基本原理
爬虫的基本原理
|
9月前
|
数据采集 安全 Python
几行代码实现爬虫
使用 Pycharm , 导入 一步 一部导入 request模块 ,几行代码实现爬虫,并对reques模块爬虫基本方法进行解释,方便以后复习
96 0
几行代码实现爬虫
|
10月前
|
数据采集 编译器 开发者
爬虫学习:XPath的使用
熟知XPath的使用来进行HTML信息锁定并获取
159 0
爬虫学习:XPath的使用
|
11月前
|
数据采集 JSON 监控
爬虫的简介
这无数个“网络爬虫”会在较短的时间内大量地访问 12306 网站以获得车票信息,当发现有票时,便会在极短的时间内订购车票。举个形象点的例子,这无数个“网络爬虫”便是你的分身,这些分身不知疲倦地访问 12306 网站以获得车票信息,当发现有票时,便会帮你订购车票。由上述描述我们得知,爬虫是一段自动抓取互联网信息的程序,从互联网上抓取对于我们有价值的信息。
98 0
|
数据采集 JavaScript 前端开发
Python爬虫:爬虫基本原理
Python爬虫:爬虫基本原理
106 0
|
数据采集 搜索推荐 Python
24、Python快速开发分布式搜索引擎Scrapy精讲—爬虫和反爬的对抗过程以及策略—scrapy架构源码分析图
【百度云搜索:http://www.lqkweb.com】 【搜网盘:http://www.swpan.cn】 1、基本概念 2、反爬虫的目的 3、爬虫和反爬的对抗过程以及策略 scrapy架构源码分析图
5953 0
|
数据采集 Python
Python爬虫入门教程 10-100 图虫网多线程爬取
1.图虫网多线程爬取-写在前面 经历了一顿噼里啪啦的操作之后,终于我把博客写到了第10篇,后面,慢慢的会涉及到更多的爬虫模块,有人问scrapy 啥时候开始用,这个我预计要在30篇以后了吧,后面的套路依旧慢节奏的,所以莫着急了,100篇呢,预计4~5个月写完,常见的反反爬后面也会写的,还有fuck login类的内容。
3066 0
|
数据采集 NoSQL 调度
scrapy分布式Spider源码分析及实现过程
分布式框架scrapy_redis实现了一套完整的组件,其中也实现了spider,RedisSpider是在继承原scrapy的Spider的基础上略有改动,初始URL不在从start_urls列表中读取,而是从redis起始队列中读取。
998 0
|
数据采集 大数据 开发者
前程无忧爬虫源码及分析(一)
一、网页分析     1.1 关键字页面(url入口)         首先在前程无忧网站上检索关键词"大数据":         跳转到如下url: https://search.51job.com/list/000000,000000,0000,00,9,99,%25E5%25A4%25A7%25E6%2595%25B0%25E6%258D%25AE,2,1.
4781 0