简单使用requests_html模块爬取51Job招聘网的招聘数据

前言

本菜鸡是python和html初学者,此文记录一下学习历程,并希望可以给有需要的同好提供一点思路。这个程序只是简单的使用了requests_html库,所以效率可能不是很高。
requests_html库介绍

库安装指令:
pip install requests_html  

思路

  1. 打开想要爬取的网站进行分析 https://jobs.51job.com/all/
  2. 以爬取不同的行业信息(岗位,公司,薪资水平)为例。最后计算各行业的平均薪资水平。
    在这里插入图片描述
    按下F12,在网页源码中找了选择不同行业的超链接。
    在这里插入图片描述
# 调用find函数,找到class='lkst'下的这一部分,再次使用find函数获得所有的超链接对象,在进行相应操作。
# 获取所有行业选项的名字和链接,以字典形式返回
def GetItems(url_html):
    items = url_html.html.find('.lkst')[1].find('a')
    names = []
    urls = []
    for item in items:
        names.append(item.text)
        urls.append(item.attrs['href'])
    return dict(zip(names,urls))
  1. 获取选择不同行业的链接之后,我们要开始抓取我们需要的信息了。
    同样是在网页源码中搜寻我们需要的信息。
    在这里插入图片描述
    在这里插入图片描述与2同理,调用find()函数,先找到class="info"的这一部分,然后在通过find()函数,获取span和超链接内容的对象,通过对象返回相应的信息。
#获取当前页面的数据信息
def GetInfo(url_html):
    infos = url_html.html.find('.info')
    jobs = []       #岗位
    company = []    #公司
    salary = []     #薪水
    for info in infos:
        spans = info.find('span')
        jobs.append(spans[0].text)
        salary.append(spans[2].text)
        
        coms = info.find('a')
        company.append(coms[1].text)
        print("{:<40}{:<40}{:<40}".format(spans[0].text, coms[1].text, spans[2].text))
    return list(zip(jobs, company, salary))
  1. 好了,我们获取到了第一页的信息,但是我们还有第二页,第三页等等。怎么办呢?让我们继续分析。
    点击第二页,我们可以发现,第n页只是在后面加了一个pn/而已,那么问题解决了,让我们继续吧。 在这里插入图片描述
#获取指定条目下所有页面的信息
def GetAllInfo(item_url):
    item_html = session.get(item_url)
    page = item_html.html.find('div.dw_page')[0].text
    page = page[page.find('共')+1:-7] # 获取页码
    
    lists = GetInfo(item_html)
    print('成功爬取第1页'.center(30,'*'))
    for i in range(2, eval(page)):
        item_html = session.get(item_url+'p'+str(i)+'/')
        lists += GetInfo(item_html)
        print(('成功爬取第'+str(i)+'页').center(30,'*'))
    return lists
  1. 既然要求薪资的平均值,我们就要处理得到的数据,也就是得到的salary。通过.text返回的是一个字符串,比如1.5千-2.5千/月,10万-20万/年。所以我们要处理数据,并且把数据单位统一(我将他处理成了以万/年为单位)。因为这个网站给的薪资是一个范围,我就返回了一个列表,列表中第一个元素是最小值,第二个元素是最大值。代码如下:
#处理salary
def str2val(salary):
# 因为有的条目没有提供薪资,也就是返回了一个空值(可能是,没研究过)所以使用了异常处理
    try:
        min, max = salary[:-3].split('-')
        min = eval(min)
        max = eval(max)
        if salary[-3:][0]=='千':
            min, max = min/10, max/10
        if salary[-3:][2]=='月':
            min, max = min*12, max*12
    except:
        return [0,0]
    else:
        return [min, max]

代码

完整代码如下,初学python,代码晦涩难懂啰嗦,请见谅。

from requests_html import HTMLSession

session = HTMLSession()
url = 'https://jobs.51job.com/all/'
main_html = session.get(url)



# 获取所有职业选项的名字和链接,以字典形式返回
def GetItems(url_html):
    items = url_html.html.find('.lkst')[1].find('a')
    names = []
    urls = []
    for item in items:
        names.append(item.text)
        urls.append(item.attrs['href'])
    return dict(zip(names,urls))


#获取当前页面的数据信息
def GetInfo(url_html):
    infos = url_html.html.find('.info')
    jobs = []       #岗位
    company = []    #公司
    salary = []     #薪水
    for info in infos:
        spans = info.find('span')
        jobs.append(spans[0].text)
        salary.append(spans[2].text)
        
        coms = info.find('a')
        company.append(coms[1].text)
        print("{:<40}{:<40}{:<40}".format(spans[0].text, coms[1].text, spans[2].text))
    return list(zip(jobs, company, salary))
    

#获取指定条目下所有页面的信息
def GetAllInfo(item_url):
    item_html = session.get(item_url)
    page = item_html.html.find('div.dw_page')[0].text
    page = page[page.find('共')+1:-7] # 获取页码
    
    lists = GetInfo(item_html)
    print('成功爬取第1页'.center(30,'*'))
    for i in range(2, 50):      #暂时先爬前50页,速度感人
        item_html = session.get(item_url+'p'+str(i)+'/')
        lists += GetInfo(item_html)
        print(('成功爬取第'+str(i)+'页').center(30,'*'))
    return lists


#处理salary
def str2val(salary):
    try:
        min, max = salary[:-3].split('-')
        min = eval(min)
        max = eval(max)
        if salary[-3:][0]=='千':
            min, max = min/10, max/10
        if salary[-3:][2]=='月':
            min, max = min*12, max*12
    except:
        return [0,0]
    else:
        return [min, max]



lists = {}
items = GetItems(main_html)
money = {k:[0,0] for k in list(items.keys())}

for key in items:
    print(('正在爬取'+key+'条目下数据').center(40,'*'))
    lists[key] = GetAllInfo(items[key])
    cnt = 0
    for l in lists[key]:
        money[key][0], money[key][1] = money[key][0]+str2val(l[2])[0], money[key][1]+str2val(l[2])[1]
        cnt += 1
    money[key][0], money[key][1] = money[key][0]/cnt, money[key][1]/cnt
    money[key][0], money[key][1] = round(money[key][0]*1000)/1000, round(money[key][1]*1000)/1000

print('-'*50)
for key in money:
    print(key+':',money[key][0],'-',money[key][1])

运行

这是爬取中的效果图:
在这里插入图片描述
至今没有解决对齐的问题,欢迎各位大牛指教一波。

这是每个行业爬取了50页计算出来的结果:
右边数据是薪资平均范围(单位年)

后端开发: 11.152 - 17.881
移动开发: 11.822 - 18.536
前端开发: 10.622 - 16.365
人工智能: 14.268 - 23.588
游戏: 10.417 - 16.647
设计: 7.721 - 11.742
测试: 8.126 - 12.348
运维/技术支持: 7.887 - 11.891
数据: 8.985 - 13.847
产品: 10.934 - 17.263
运营: 8.162 - 12.832
电子商务: 7.536 - 12.212
技术管理: 11.658 - 17.871
半导体/芯片: 10.006 - 15.983
电子/电器/仪器仪表: 8.874 - 14.226
通信技术开发及应用: 8.996 - 14.178
销售管理: 10.63 - 16.942
销售人员: 8.391 - 13.668
销售行政及商务: 6.492 - 9.582
客服及支持: 6.639 - 10.186
财务/审计/税务: 7.148 - 10.184
金融/证券/期货/投资: 10.917 - 18.156
银行: 9.027 - 13.874
保险: 9.28 - 14.415
生产/营运: 7.775 - 11.444
质量安全: 6.898 - 10.017
工程/机械/能源: 8.327 - 12.62
汽车研发设计: 10.85 - 17.003
汽车制造: 7.615 - 11.294
汽车销售与服务: 6.995 - 11.448
技工普工: 5.665 - 7.826
服装/纺织/皮革: 7.654 - 11.591
采购: 7.12 - 10.431
贸易: 6.78 - 11.52
物流/仓储: 6.157 - 8.819
生物/制药/医疗器械: 8.312 - 13.113
化工: 7.563 - 11.555
医院/医疗/护理: 7.314 - 11.372
广告: 7.557 - 11.453
公关/媒介: 7.711 - 11.795
市场/营销: 9.469 - 14.564
影视/媒体: 7.618 - 12.36
编辑出版: 6.424 - 9.777
艺术/设计: 7.428 - 11.33
建筑规划与设计: 9.246 - 14.157
建筑工程与装潢: 8.383 - 12.464
房地产开发: 11.39 - 16.694
房地产销售与中介: 9.468 - 15.086
物业管理: 6.795 - 9.635
人力资源: 7.057 - 10.201
高级管理: 14.012 - 22.077
行政/后勤: 5.212 - 7.435
咨询/顾问: 8.907 - 14.5
律师/法务/合规: 8.774 - 13.625
教师: 7.288 - 11.548
培训: 8.081 - 13.132
科研: 10.152 - 16.266
餐饮服务: 6.221 - 8.724
酒店旅游: 6.482 - 9.66
美容保健: 7.553 - 12.365
百货零售: 6.682 - 10.652
交通运输服务: 7.039 - 10.077
家政保洁: 4.749 - 6.892
公务员: 11.536 - 17.577
翻译: 6.864 - 10.478
在校学生: 4.295 - 6.506
储备干部/培训生/实习生: 5.406 - 8.026
兼职: 2.199 - 3.35
环保: 7.39 - 11.334
农/林/牧/渔: 6.952 - 10.401
机械机床: 6.126 - 8.654
印刷包装: 6.181 - 8.929
运动健身: 7.173 - 11.507
休闲娱乐: 6.86 - 11.206
其他: 6.344 - 9.385

爬取全部数据的正在云服务器上跑(跑了一天了,效率有点低,大概只能1s中一页,一个行业大概5k页),有结果会贴出来。

结果已经出来了:
后端开发: 11.705 - 18.97
移动开发: 13.459 - 21.43
前端开发: 11.512 - 17.951
人工智能: 15.675 - 26.38
游戏: 12.138 - 19.734
设计: 8.518 - 13.297
测试: 10.839 - 16.572
运维/技术支持: 8.748 - 13.668
数据: 8.71 - 13.786
产品: 12.405 - 19.685
运营: 8.074 - 12.847
电子商务: 7.581 - 12.166
技术管理: 13.996 - 21.694
半导体/芯片: 11.624 - 19.374
电子/电器/仪器仪表: 9.374 - 15.07
通信技术开发及应用: 9.279 - 15.008
销售管理: 11.316 - 18.503
销售人员: 8.157 - 13.415
销售行政及商务: 6.986 - 10.565
客服及支持: 6.712 - 10.097
财务/审计/税务: 7.556 - 10.978
金融/证券/期货/投资: 11.463 - 18.294
银行: 9.212 - 14.399
保险: 9.915 - 14.96
生产/营运: 8.485 - 12.507
质量安全: 7.201 - 10.57
工程/机械/能源: 8.577 - 13.273
汽车研发设计: 11.398 - 18.044
汽车制造: 7.689 - 11.552
汽车销售与服务: 7.279 - 11.752
技工普工: 5.847 - 8.244
服装/纺织/皮革: 7.485 - 11.2
采购: 7.473 - 11.156
贸易: 7.034 - 12.005
物流/仓储: 6.794 - 9.995
生物/制药/医疗器械: 8.795 - 14.122
化工: 7.851 - 12.321
医院/医疗/护理: 8.728 - 15.318
广告: 9.484 - 14.377
公关/媒介: 8.597 - 13.109
市场/营销: 9.543 - 15.014
影视/媒体: 7.809 - 12.877
编辑出版: 7.897 - 12.712
艺术/设计: 7.705 - 11.91
建筑规划与设计: 10.898 - 17.186
建筑工程与装潢: 9.061 - 13.751
房地产开发: 13.804 - 21.104
房地产销售与中介: 9.0 - 14.073
物业管理: 7.298 - 10.402
人力资源: 7.511 - 11.106
高级管理: 18.213 - 28.926
行政/后勤: 5.54 - 7.935
咨询/顾问: 9.01 - 14.411
律师/法务/合规: 9.842 - 15.447
教师: 7.699 - 12.227
培训: 8.758 - 14.092
科研: 11.124 - 17.863
餐饮服务: 6.56 - 9.411
酒店旅游: 7.287 - 10.955
美容保健: 7.521 - 12.125
百货零售: 6.173 - 9.527
交通运输服务: 8.354 - 12.037
家政保洁: 5.191 - 7.543
公务员: 11.583 - 17.739
翻译: 7.369 - 11.077
在校学生: 5.561 - 8.404
储备干部/培训生/实习生: 6.478 - 9.768
兼职: 2.572 - 3.822
环保: 7.672 - 11.933
农/林/牧/渔: 7.64 - 11.827
机械机床: 6.268 - 8.915
印刷包装: 6.096 - 8.703
运动健身: 8.158 - 12.732
休闲娱乐: 7.058 - 11.921
其他: 11.622 - 16.675

猜你喜欢

转载自blog.csdn.net/Thebaldslasher/article/details/106947349