1010cc时时彩标准版 > 三分时时彩1010CC > 拉勾网职位列表和详情,二级页面

原标题:拉勾网职位列表和详情,二级页面

浏览次数:53 时间:2019-10-07

我们改进一下代码:

图片 1动态填充数据页面流程

Python里面,如果你需要临时禁用一行代码,可以在它开头添加井号#;如果你需要临时禁用多行代码,那么需要在开始和结尾添加三个单引号'''

读取二层页面,获取单个职位要求的详情

在网页里面点击任意一个职位进入查看详情,例如https://www.lagou.com/jobs/4263258.html

图片 2image.png

参照我们最开始的方法可以发现,我们需要的信息就在右键html网页源代码里面,就在一个class='job_bt'的dd标签里面:

图片 3image.png

我们需要使用beautifulsoup来处理html内容:

#cell-2.5from bs4 import BeautifulSoupdef readJobDetails: html = requests.get('https://www.lagou.com/jobs/' str '.html', headers=headers) soup = BeautifulSoup(html.text, 'html.parser') res=soup.find('dd','job_bt').text.replace return resprint(readJobDetails 

这里.text.replace去掉了回车换行,最后一行print(readJobDetails执行了测试,成功了就可以把它删除。成功的话会输出一大堆字符串,和上面html代码截图差不多。

1.1 前提数据

这里需要知道页面的 id 才能生成详细的链接,在 Python爬虫框架Scrapy实战 - 抓取BOSS直聘招聘信息 中,我们已经拿到招聘信息的大部分信息,里面有个 pid 字段就是用来唯一区分某条招聘,并用来拼凑详细链接的。

是吧,明眼人一眼就看出来了。


下面是利用上一篇文章介绍的Excel数据透视表方法绘制的统计图

回顾上面截图的浏览器Request请求的Headers信息,实际上浏览器发送请求的时候还携带了很多Request headers,以及Form data数据(对应我们以前提到过的Parameters信息)。

url='https://www.zhipin.com/c101020100/h_101020100/?query=人工智能&page='headers={ 'user-agent':'Mozilla/5.0'}page=1hud=['职位名','薪资1','薪资2','地点','经验','学历','公司行业','融资阶段','公司人数','发布日期','发布人']print('t'.joinimport requestsfrom bs4 import BeautifulSoupfor n in range: html=requests.get(url str,headers=headers) page =1 soup = BeautifulSoup(html.text, 'html.parser') for item in soup.find_all('div','job-primary'): shuchu=[] shuchu.append(item.find('div','job-title').string) #职位名 #读取每个职位的详细信息页面 link=item.find('div','info-primary').find.find['href'] print #print('t'.join

存储数据,把每个职位信息存为单独文件

因为数据很多,我们也说不准以后会用到哪个,所以我们把每个job都存储为一个文件,以后只要读取就可以了,避免因为少存了数据还要重新抓取的麻烦。

改进上面的cell-3代码(为确保可以运行,必须在Notebook代码文件所在文件夹下创建data文件夹,进入data文件夹依次创建lagou_ai文件夹、jobs文件夹,否则会报错):

#cell-3import jsonimport requestsjsonData = requests.get(url, params=params, headers=headers)json.loads(jsonData.text)jobs = data['content']['positionResult']['result']for job in jobs: fname='./data/lagou_ai/jobs/' str(job['positionId']) '.json' with open(fname,'w') as f: f.write(json.dumps f.close()

代码说明:

  • 这个代码将自动存储15个.json文件在./data/lagou_ai/jobs/文件夹下。
  • 这次没有使用pandas模块,仍然使用了json模块,因为pandas不方便把json变为可以写入文件的字符串,而json.dumps就很好用。
  • fname='./data/lagou_ai/jobs/' str(job['positionId']) '.json',这是利用每个职位索引positionId都是唯一不重复的特性,创建不重复的文件名。

完整运行代码,可以在./data/lagou_ai/jobs/文件夹下生成15个数字文件名的文件,你可以尝试用下面的代码打开其中一个,试试看pandas是否可以正常使用这些数据,注意这里的file:后面内容应该是完整路径(苹果系统的Command Alt C):

import pandas as pddata = pd.read_json('file:/Users/zhyuzh/Desktop/Jupyter/spiders/data/lagou_ai/jobs/3128720.json', typ='series')print(data['positionName'])

2.6 异常值分析 [2017-12-19] 更新

  1. 岗位要求工作年限和职位描述里的要求不一致,比如岗位列表里要求的是1年以内,但是职位描述里却是2年以上工作经验,这是由于 HR 填写不规范引起的误差。
  2. 由第1点引起的另一个问题,就是与工作年限要求不对应的薪水,使计算的平均薪水偏高。比如一条记录,年限要求是一年以内,所以等级为2,但是薪水却是20k-30k,实际上这是等级为3的薪水,这里就得校正 level 字段,目前只是手动的把几个较高的记录手动改了,都校正过来很困难,得文本分析招聘要求。

使用阿里云天池的Notebook或者Anaconda的Jupyter Notebook都可以,编写以下代码,获取整个页面的html文件数据。

图片 4思必驰招聘职位

对于

完善代码,读取更多职位列表页面

我们来把代码整合一下,刚才我们只读取过一页15个职位基本信息,或者单个职位的详细信息,我们把它整合到一起,最终代码如下(注意替换headers并去除content-length):

# coding: utf-8# ## 拉钩搜索‘人工智能’职位列表,包含二级页面详情# ### 设置# In[1]:url = 'https://www.lagou.com/jobs/positionAjax.json?needAddtionalResult=false'params = { 'first': 'false', 'pn': '1', 'kd': '人工智能',}savePath='./data/lagou_ai'headers='''!!!必须替换POST /jobs/positionAjax.json?needAddtionalResult=false HTTP/1.1Host: www.lagou.comConnection: keep-aliveOrigin: https://www.lagou.comX-Anit-Forge-Code: 0User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36Content-Type: application/x-www-form-urlencoded; charset=UTF-8Accept: application/json, text/javascript, */*; q=0.01X-Requested-With: XMLHttpRequestX-Anit-Forge-Token: NoneReferer: https://www.lagou.com/jobs/list_人工智能?labelWords=&fromSearch=true&suginput=Accept-Encoding: gzip, deflate, brAccept-Language: zh-CN,zh;q=0.9,en;q=0.8,zh-TW;q=0.7Cookie: JSESSIONID=ABAAABA...538875676'''# In[2]:#转换headers为字典def str2obj(s, s1=';', s2='='): li = s.split res = {} for kv in li: li2 = kv.split if len > 1: res[li2[0]] = li2[1] return resheaders = str2obj(headers, 'n', ': ')# ### 读取单个职位详情的函数# In[3]:from bs4 import BeautifulSoupdef readJobDetails: html = requests.get( 'https://www.lagou.com/jobs/'   str   '.html', headers=headers) soup = BeautifulSoup(html.text, 'html.parser') res = soup.find('dd', 'job_bt').text.replace return res# ### 发起请求# In[4]:import jsonimport requestsimport timefor n in range: params['pn'] = n jsonData = requests.get(url, params=params, headers=headers) data = json.loads(jsonData.text) jobs = data['content']['positionResult']['result'] for job in jobs: pid = str(job['positionId']) fname = savePath   '/jobs/'   pid   '.json' job['details'] = readJobDetails(job['positionId']) with open(fname, 'w') as f: f.write(json.dumps f.close() print('>Got job:', pid) time.sleep time.sleepprint('>Finished!')

代码的几个说明:

  • 顶部paramspn恢复为1,之前我们一直使用的是2...
  • 将存储文件的目录放到开始savePath设置,方便以后修改
  • def readJobDetails...必须要放在for n in range...前面,先def然后才能使用。
  • 因为过程超过400秒也就是有八九分钟,所以用print('>Got job:', pid)只是让过程能够有点反应,看上去不像死机。
  • 每读取一页列表,time.sleep休息1秒,每读取一个详情页面也要time.sleep休息一秒。这样比较低调不容易被封禁。

运行整个代码,可以在./data/lagou_ai/jobs下生成450个xxxxxxx.json文件,你可以在资源管理器或者访达中查看文件一个个变多以确保程序顺路进行中。

最后别忘了测试一下存储的数据是否正确:

import pandas as pddata = pd.read_json('file:/Users/zhyuzh/Desktop/Jupyter/spiders/data/lagou_ai/jobs/5177921.json', typ='series')print(data['positionName'])print(data['details'])

2.4 区分开<岗位职责>和<任职要求>

对于作者这个初学者来说,这里还没有什么好的方法,知道的同学,请务必联系作者,联系方式在个人博客里

so , i'm sorry.

为什么这两个不好划分出来呢?

因为这里填的并不统一,可以说各种花样,有的要求在前,职责在后,有的又换个名字区分。目前看到的关于要求的有['任职条件', '技术要求', '任职要求', '任职资格', '岗位要求']这么多说法。然后顺序还不一样,有的要求在前,职责在后,有的又反之。

举个栗子

会基本的php编程!能够修改简单的软件!对云服务器和数据库能够运用!懂得微信公众账号对接和开放平台对接!我们不是软件公司,是运营公司!想找好的公司学习的陕西基本没有,要到沿海城市去!但是我们是实用型公司,主要是软件应用和更适合大众!

啥也不说的,这里可以认为这是一条脏数据了。

再举个栗子

PHP中级研发工程师(ERP/MES方向)
1、计算机或相关学科本科或本科以上学历;
2、php和Java script的开发经验。
3、Linux和MySQL数据库的开发经验;
5、有ERP、MES相关开发经验优先;
6、英语的读写能力;
7、文化的开放性;
我们提供
1、有趣的工作任务;
2、多元的工作领域;
3、与能力相关的收入;
4、年轻、开放并具有创造力的团队和工作氛围;
5、不断接触最新科技(尤其是工业4.0相关);
6、可适应短期出差(提供差补);

这个只有要求,没职责,还多了个提供,我乐个趣 ╮(╯▽╰)╭

所以,气的想骂人。

  • '-'.join将列表集合['aa','bb','cc']合并成字符串'aa-bb-cc'。我们用t拼合成最后输出shuchu的内容。
  • 集合.append,把a加入到集合最后面,之前是[b,c]的话就会变成[b,c,a]。我们用这个办法逐个的把数据添加到集合的每个单元中。
  • 字符串.split,和join相反,split是把字符串切成很多单元,再组成集合,小括号内就是分隔符号,比如'aa-bb-cc'分割之后就成为`['aa','bb','cc']。
  • import timetime.sleep,每次请求之后停止休息1秒,避免频繁发送请求被Boss直聘服务器屏蔽。如果我们请求的频率远超过正常人点击频率,那么很可能被服务器看出是爬虫,进而不再理睬我们的请求,也不会发送数据给我们。

案例是拉勾网抓取某个公司全部招聘信息,然后分析中大型人工智能公司的人才需求分布情况。

网络数据抓取-Python-爬虫-Header-Boss直聘

分析页面,寻找数据来源

打开拉勾网,搜索“人工智能”得到下面这个页面。共30页,每页展示15个职位,应该最多共计450个职位,但不知道为什么页面上写[职位]。

图片 5image.png

【右键-查看网页源代码】,然后搜索任意一个职位中比较独特的单词,比如“骏嘉财通”,搜不到,这说明数据肯定不在html源代码里面。

图片 6image.png

只能从网络面板中查找了,,切换到面板。为了清晰一些,我们先点清除,然后点底部的页面分页按钮,得到如下图情况,注意type类型为xhr的两个请求,它们很可能包含我们所需要的数据:

图片 7image.png

点击请求查看详细,如下图,在预览面板中看到,positionAjax.json?needAddtionalResult=false就是我们需要的请求。

图片 8image.png

如上图,职位列表数据存在于这个请求结果的.content.positionResult.result下面。

1.3 爬虫用到的库

使用的库有

  • requests
  • BeautifulSoup4
  • pymongo

对应的安装文档依次如下,就不细说了

  • 安装 Requests - Requests 2.18.1 文档
  • 安装 Beautiful Soup - Beautiful Soup 4.2.0 文档
  • PyMongo安装使用笔记

这一篇我们看一下更复杂的情况,爬取Boss直聘这个招聘网站的招聘信息,进而简单分析人工智能行业的招聘情况。

我们注意到searchPosition.json这行,它的类型是xhr,数据请求都是这个类型的。

BeautifulSoup获取元素属性的方法是直接使用['属性名'],比如这里我们需要获取href属性,那么就只要找到这个a标记,然后.['href']就可以得到链接地址了。

发起请求,获取职位信息列表

先测试一个页面,只获取职位标题:

#cell-3import requestsimport pandas as pdjsonData = requests.get(url, params=params, headers=headers)data = pd.read_json(jsonData.text, typ='series')jobs = data['content']['positionResult']['result']print(json.dumps(jobs[0], indent=2, ensure_ascii=False))

代码的一些说明:

  • 这次我们没有使用import json模块,而是使用了更为强大的pandas模块,它是最常用的数据处理模块之一。
  • 这里的jobs = data['content']['positionResult']['result']请参照上面Network面板请求的preview预览对照。
  • json.dumps(jobs[0], indent=2,ensure_ascii=False)jobs[0]是指职位列表的第一个,json.dumps是把它按正常格式显示出来,否则直接print也可以,但就会混乱不换行。

运行全部代码,正常应该输出第二页第一个职位的全部信息:

图片 9image.png

这样我们就可以知道:

  • jobs[0]['positionId']就是职位索引,是唯一性的数字
  • jobs[0]['positionName']就是职位名
  • jobs[0]['workYear']就是要求工作经验
  • jobs[0]['education']就是要求学历
  • jobs[0]['city']就是工作地点
  • jobs[0]['salary']就是薪资
  • jobs[0]['companyFullName']就是公司名
  • jobs[0]['industryField']就是公司行业,“金融”
  • jobs[0]['companySize']就是公司员工数量
  • jobs[0]['firstType']就是这个职位的类别,“产品|需求|项目类”,
  • jobs[0]['secondType']就是这个职位的二级分类,“数据分析”,
  • ...

2.7 失效值排除 [2017-12-19] 更新

首先这里需要一个判断某条招聘是否还挂在网站上的方法,这个暂时想到了还没弄

然后对于发布时间在两个月之前的数据,就不进行统计计算


ok ,现在我们的数据基本成这样了

{
    "_id" : ObjectId("5a30ad2068504386f47d9a4b"),
    "city" : "苏州",
    "companyShortName" : "蓝海彤翔",
    "companySize" : "100-499人",
    "education" : "本科",
    "financeStage" : "B轮",
    "industryField" : "互联网",
    "level" : 3,
    "pid" : "11889834",
    "positionLables" : [ 
        "PHP", 
        "ThinkPHP"
    ],
    "positionName" : "php研发工程师",
    "salary" : {
        "avg" : 7500.0,
        "low" : 7000,
        "high" : 8000
    },
    "time" : "2017-06-06",
    "updated_at" : "2017-12-13 18:31:15",
    "workYear" : "1-3年",
    "detail" : "1、处理landcloud云计算相关系统的各类开发和调研工作;2、处理coms高性能计算的各类开发和调研工作岗位要求:1、本科学历,两年以上工作经验,熟悉PHP开发,了解常用的php开发技巧和框架;2、了解C  ,python及Java开发;3、有一定的研发能力和钻研精神;4、有主动沟通能力和吃苦耐劳的精神。",
    "location" : "苏州市高新区科技城锦峰路158号101park8幢"
}

由于还没到数据展示的时候,所以现在能想到的就是先这样处理了

项目开源地址:

运行这个代码,会output输出页面的标记代码,但你仔细看会发觉有什么不对,好像少了很多,而且会看到这个信息。

图片 10复制请求地址

如果你希望成为一个真正的爬虫专家,那么你需要认真的学习一些计算机网络通信的基础知识,可以在网上购买一些大学计算机通信专业的课本来看。——当然这不是我推荐每个人去做的。

总结

  • 先分析页面,知道数据从哪里来、什么格式?(网页源代码html?Network面板的xhr请求到的json数据?)
  • 然后找到对应的headers和params(如果有的话,详情页就没有)
  • 根据数据来源格式确定使用BeautifulSoup还是json模块来解析,具体解析方法要多看教程多查资料多学习
  • 发起Request请求get数据,然后解析到我们需要的内容
  • 利用def定义不同的函数处理单独的请求可以让代码更清晰
  • 把获取的内容存储到文件(简单横竖列表数据存.csv,复杂结构存.json),注意要转为字符串存储,注意文件名要唯一。
  • 尽可能在必要的位置合理的使用time.sleep延缓一下
  • 代码要一点点测试,如果要for n in range那就先for n in range试一下能不能成功。

2.2 校正薪水以数字保存

"salary" : "5K-12K",

#处理成下面的格式
"salary" : {
    "low" : 5000,
    "high" : 12000,
    "avg" : 8500.0
},

# 薪水处理成数字,符合 xk-yk 的数据处理,不符合的跳过
def clear_salary():
    items = db.jobs_lagou_php.find({})
    for item in items:
        if type(item['salary']) == type({}):
            continue
        salary_list = item['salary'].lower().replace("k", "000").split("-")
        if len(salary_list) != 2:
            print(salary_list)
            continue
        try:
            salary_list = [int(x) for x in salary_list]
        except:
            print(salary_list)
            continue
        item['salary'] = {
            'low': salary_list[0],
            'high': salary_list[1],
            'avg': (salary_list[0]   salary_list[1]) / 2
        }
        update(item)
    print('ok')

[2017-12-19更新] 这里在处理 Boss 直聘的数据时,比较简单正常,但是后续抓到拉勾网的数据,拉勾网的数据有些不太规范。比如有‘20k以上’这种描述


Network网络面板包含了所有向服务器发出的请求的信息,如图所示,这一行?query=人工智能&page=1就是我们代码里面发送的那个请求,点击它,可以看到它的更多信息:

打开Notebook,新建Python 3文件,粘贴过去。

如果你的代码本来好好地,然后就不能正常运行,或者能运行但是详情字段都输出None,那么请做以下尝试:

这次我们来比较完整的抓取拉勾网上面“人工智能”相关招聘信息以及招聘要求详情。

四、help

这里完全就是作者本人依据个人微薄的见识,主观臆断做的一些事情,所以大家有什么点子和建议,都可以评论一下,多交流交流嘛。

后续会公开所有数据,大家自己可以自己分析分析。

我们太年轻,以致都不知道以后的时光,竟然那么长,长得足够让我们把一门技术研究到顶峰,乱花渐欲迷人眼,请不要忘了根本好吗。

生活总是让我们遍体鳞伤,但到后来,那些受伤的地方一定会变成我们最强壮的地方。 —海明威 《永别了武器》

图片 11请求头信息

#单元2import requestsjsonData=requests.get(url,params=params,headers=headers)print(jsonData.text)

我们需要让爬虫自动的打开每个详细页面,并提取里面的有用信息,以便于我们存储到Excel表格里面进行分析。

每个人的智能决策新时代

如果您发现文章错误,请不吝留言指正;如果您觉得有用,请点喜欢;如果您觉得很有用,欢迎转载~

END

Pyhton爬虫实战 - 抓取BOSS直聘职位描述 和 数据清洗

url='https://www.zhipin.com/c101190400/h_101190400/?query=人工智能&page=1'headers={ 'user-agent':'Mozilla/5.0'}import requestsfrom bs4 import BeautifulSouphtml=requests.get(url,headers=headers)print(html.text)

图片 12获取数据成功

目前还不确定Boss直聘的反爬虫机制,不过下一篇我们一定会深入讨论更多内容,届时也许会有更好办法。

设置参数,复制url、header和params

点击请求可以直接【右键-Copy-Copy ...】复制到链接地址link address,复制到请求头request headers。在右侧Headers面板底部有可以看到params的列表,其中first看不出意思,pn应该就是页数,大概是page number的意思,kd不知什么意思,但肯定就是我们的搜索词。

图片 13image.png

按照以前我们的方法,在Notebook中新建Python 3文件,复制粘贴两个cell单元,代码如下(headers需要替换成你自己复制的内容)。

注意一定要去掉Content-Length: ...一行

#cell-1url = 'https://www.lagou.com/jobs/positionAjax.json?needAddtionalResult=false'params = { 'first': 'false', 'pn': '2', 'kd': '人工智能',}headers='''POST /jobs/positionAjax.json?needAddtionalResult=false HTTP/1.1Host: www.lagou.comConnection: keep-aliveOrigin: https://www.lagou.comX-Anit-Forge-Code: 0User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36Content-Type: application/x-www-form-urlencoded; charset=UTF-8Accept: application/json, text/javascript, */*; q=0.01X-Requested-With: XMLHttpRequestX-Anit-Forge-Token: NoneReferer: https://www.lagou.com/jobs/list_人工智能?labelWords=&fromSearch=true&suginput=Accept-Encoding: gzip, deflate, brAccept-Language: zh-CN,zh;q=0.9,en;q=0.8,zh-TW;q=0.7Cookie: JSESSIONID=ABAAABAAAGFA......f756e6=1538875676'''

#cell-2 转换headers为字典def str2obj(s, s1=';', s2='='): li = s.split res = {} for kv in li: li2 = kv.split if len > 1: res[li2[0]] = li2[1] return resheaders = str2obj(headers, 'n', ': ')

1.5 再啰嗦几句

在 上一篇文章 中只是爬了 上海-PHP 近300条数据,后续改了代码,把12个城市的 PHP 相关岗位的数据都抓下来了,有3500 条数据,慢慢爬吧,急不来。

像这样
图片 14
图片 15

再次运行,就可以得到完整的页面数据了。这里主要是添加了headers={...}对象,headers对象只有一个user-agent字段属性,用冒号隔开它的值Mozilla/5.0(这里我们偷懒只留了开头Mozila火狐浏览器的信息)

图片 16Headers详细信息和之前的稍有不同,它没有Parameters数据(因为地址栏没有?aaa=xxx&bbb=yyy这类结尾了),但是多了Form Data表单数据,其实和Parameters作用相同,就是向服务器说明你要哪个公司(companyId)的数据、第几页(pageNo)、每页多少个职位(pageSize)等等。

url='https://www.zhipin.com/c101020100/h_101020100/?query=人工智能&page='headers={ 'user-agent':'Mozilla/5.0'}page=1hud=['职位名','薪资1','薪资2','地点','经验','学历','公司行业','融资阶段','公司人数','发布日期','发布人']print('t'.joinimport requestsfrom bs4 import BeautifulSoupfor n in range: html=requests.get(url str,headers=headers) page =1 soup = BeautifulSoup(html.text, 'html.parser') for item in soup.find_all('div','job-primary'): shuchu=[] shuchu.append(item.find('div','job-title').string) #职位名 ... print('t'.join

2.3 根据 工作经验年限 划分招聘等级

# 校正拉勾网工作年限描述,以 Boss直聘描述为准
def update_lagou_workyear():
    items = db.jobs_lagou_php.find({})
    for item in items:
        if item['workYear'] == '应届毕业生':
            item['workYear'] = '应届生'
        elif item['workYear'] == '1年以下':
            item['workYear'] = '1年以内'
        elif item['workYear'] == '不限':
            item['workYear'] = '经验不限'
        update_lagou(item)
    print('ok')

# 设置招聘的水平,分两次执行
def set_level():
    items = db.jobs_zhipin_php.find({})
    # items = db.jobs_lagou_php.find({})
    for item in items:
        if item['workYear'] == '应届生':
            item['level'] = 1
        elif item['workYear'] == '1年以内':
            item['level'] = 2
        elif item['workYear'] == '1-3年':
            item['level'] = 3
        elif item['workYear'] == '3-5年':
            item['level'] = 4
        elif item['workYear'] == '5-10年':
            item['level'] = 5
        elif item['workYear'] == '10年以上':
            item['level'] = 6
        elif item['workYear'] == '经验不限':
            item['level'] = 10
        update(item)
    print('ok')

这里有点坑的就是,一般要求经验不限的岗位,需求基本都写在任职要求里了,所以为了统计的准确性,这个等级的数据,后面会被舍弃掉。

[2017-12-14更新] 从后续的平均数据来看,这里的经验不限,一般要求的是1-3年左右,但是还是建议舍弃掉。
[2017-12-19更新] 拉勾网的职位描述和 Boss直聘稍有不同,需要先校正,然后再设置等级


作为一个互联网或科技企业的你,一定很关注你当前的职位的分布情况吧,现在可以自己动手从Boss直聘网站的大数据上进行科学分析了!换一个城市,换一个行业,尝试更多的可能,从分析图表中总结规律,推测趋势。

上面看到,我们需要的数据都在searchPosition.json这个Request请求里面,【右键-Copy-Copy link address】复制请求地址。

这里我们使用了几个新的知识:

二、数据清洗

注,300个职位数据规模还很小,而且由于Boss直聘的搜索问题,其中掺杂了大量的实际与人工智能无关的职位,我们的分析方法还是很原始很粗糙的,仅供参考。随着后续学习我们会逐步加深这方面的研究。

这个格式看上去比html一堆尖括号标记看上去舒服多了。但如何拿到这个数据呢?

图片 17抓取流程

三、展望和设想

首先这个小玩意数据量并不够多,因为爬取时间短,站点唯一,再者广度局限在 PHP 这一个岗位上,以致存在一定的误差。

所以为了数据的丰富和多样性,这个爬虫是一定要持续跑着的,至少要抓几个月的数据才算可靠吧。

然后准备再去抓下拉勾网的招聘数据,这也是个相对优秀的专业 IT 招聘网站了,数据也相当多,想当初找实习找正式工作,都是在这两个 APP 上找的,其他的网站几乎都没看。

最后,对于科班出身的学弟学妹们,过来人说一句,编程相关的职业就不要去志连、钱尘乌有、five eight桐城了,好吗?那里面都发的啥呀,看那些介绍心里没点数吗?

图片 18Boss直聘苏州市人工智能职位搜索

#cell-2def str2obj(s,s1=';',s2='='): li=s.split res={} for kv in li: li2=kv.split if len>1: res[li2[0]]=li2[1] return resheaders=str2obj(headers,'n',': ')jobheaders=str2obj(jobheaders,'n',': ')

建议你新建一个文件,然后使用下面精简过的代码进行测试(这里改为range只读取第1页):

一、抓取详细的职位描述信息

<h3 >您暂时无法继续访问~</h3><p>由于您当前网络访问页面过于频繁,可能存在安全风险,我们暂时阻止了您的本次访问,24小时将自动解除限制。</p>

这里没有直接使用,而是def了一个函数getJobs,带有三个参数compId公司序号,school是否社招,pageCount一共有多少页。

如果你被封禁了又急需解锁,那么恐怕最快的办法就是换个IP了,可以试试看换台电脑或者换到别的网线接口上,如果是家庭宽带,也可以试试看拔掉网线过几分钟再插上。

1.2 详情页分析

详情页如下图所示

图片 19

在详情页中,比较重要的就是职位描述工作地址这两个

由于在页面代码中岗位职责任职要求是在一个 div 中的,所以在抓的时候就不太好分,后续需要把这个连体婴儿,分开分析。


图片 20Network面板

zidian={ 'a':'1', 'b':{ 'b1':'2-1', 'b2':'2-2' }}

这种封禁一般是几分钟到1小时,罕见彻底封禁不自动解禁的。

2.1 校正发布日期

"time" : "发布于03月31日",
"time" : "发布于昨天",
"time" : "发布于11:31",

这里拿到的都是这种格式的,所以简单处理下

import datetime

from pymongo import MongoClient

db = MongoClient('127.0.0.1', 27017).iApp

def update(data):
    return db.jobs_php.update_one({"_id": data['_id']}, {"$set": data})

# 把时间校正过来
def clear_time():
    items = db.jobs_php.find({})
    for item in items:
        if not item['time'].find('布于'):
            continue
        item['time'] = item['time'].replace("发布于", "2017-")
        item['time'] = item['time'].replace("月", "-")
        item['time'] = item['time'].replace("日", "")
        if item['time'].find("昨天") > 0:
            item['time'] = str(datetime.date.today() - datetime.timedelta(days=1))
        elif item['time'].find(":") > 0:
            item['time'] = str(datetime.date.today())
        update(item)
    print('ok')

本文由1010cc时时彩标准版发布于三分时时彩1010CC,转载请注明出处:拉勾网职位列表和详情,二级页面

关键词:

上一篇:1010cc时时彩标准版Golang事务模型,DDD分层架构的

下一篇:没有了