爬虫练习-boss直聘数据相关岗位分析(一)

初识爬虫

工作期间,初识爬虫,结合自己工作需要遂萌生了一个有趣的想法----通过爬取招聘网站某些岗位的信息,来了解该岗位在招聘市场以及如今的大环境下的需求及基本情况。


项目准备

1.数据来源:

boss直聘网站,"www.zhipin.com"

2.需要的数据:

搜索界面

发现界面内的:岗位名称、薪酬、工作地点、工作经验、学历、企业信息(公司名、行业、阶段、规模)都是需要的信息。更详细的信息可以通过进入岗位具体页面获得。

3.思路

那么知道需要获得的信息后要如何获取信息呢?先下载页面,后解析。需要得到每个页面的url,观察发现:

检查界面

https://www.zhipin.com/c100010000/h_100010000/?query=%E6%95%B0%E6%8D%AE&page=2&ka=page-2
1."https://www.zhipin.com/c100010000/h_100010000/?query="
2.%E6%95%B0%E6%8D%AE
3.&page=2&ka=page-2

url由可以拆分成1,2,3这三部分,2是检索岗位中文字符的转码,3是页码,在1,2固定的前提下,只要改变页码就能不断生成新的url。

但是问题来了,当给定一个岗位时,页面最多只能显示10页的数据,这个数据量明显是不够的,那么如何解决这个问题来获得大量更多的数据呢?

按类别搜索结果

我们发现,在工作经验等类别标签下有许多详细的选项,每个选项都能有一堆页码可以显示,于是爬虫思路改为:先获得各个类别标签下的url,再拼入岗位名称和页码。

基于此,接下来就是见证奇迹的时刻了!


4.操作

4.1爬取网页信息

import requests
from bs4 import BeautifulSoup
import re
import pandas as pd
import os
import glob
import collections
#获得网页数据
def get_web(url):
    #伪装自己,不被反爬
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/534.57.2 (KHTML, like Gecko) Version/5.1.7 Safari/534.57.2' 
    }
    req = requests.get(url,headers = headers)
    text = req.text
    return text

'''
请自行更改文件路径
'''
#获得url-list,input:soup后的lxml文件
def get_info(List):
    url = []
    for x in List.find_all('a'):
        url_raw = x['href'].split('%')[0]
        for i in range(1,11):
            mid = 'http://www.zhipin.com'+url_raw+'='
        url.append(mid)
    return url[0:15]


#得到url-list,input:是下载的一个页面文件;output:两个字典url字典和详细类别字典
def get_url_list(file):
    f = open('/Users/tony/Desktop/招聘岗位数据分析/raw_data/'+file)
    text = f.read()
    soup = BeautifulSoup(text,'lxml')
    soup2 = soup.find_all('ul')[4:9]
    #类别下详细分类
    soup3 = [x.get_text().split('\n')[1:-1] for x in soup2]
    #类别
    soup4 = ['exp','degree','salary','stage','scale']
    #得到url
    num = 0
    dt_url={}
    Dict={}
    for i in soup2:
        url_raw = get_info(i)
        key = soup4[num]
        dt_url[key] = url_raw
        Dict[key] = soup3[num]
        num+=1
    return dt_url,Dict

#得到字典{'exp':[],'salary':[].....}
dt_url,Dict = get_url_list('数据page1.txt')
'''
因为不考虑类别抓的数据很少,所以需要考虑类别,按'exp','degree','salary','stage','scale'来取数据,则需要获得它们对应的url
以上两个函数最终得到类别对应的初始url和类别中包含的详细分类情况。
'''
#拼接url,dt_url是一个字典;参数分别是:检索文字,页码,类别,类别url字典。
def get_url(strings,page_num,types,dt_url):
    url = [x+strings+'&page='+str(page_num)+'&ka=page-'+str(page_num) for x in dt_url[types]]
    return url


#strings-岗位关键词;page_num-要爬的总页码;types-按照那些属性爬取:exp,salary....参数:同上,开始结束页码。
def get_txt(strings,types,dt_url,start,end):
    for x in range(start,end+1):
        #得到一个types下某一页的URL列表
        URL = get_url(strings,x,types,dt_url)
        count = 0
        for url in URL:
            count+=1
            text = get_web(url)
            with open('/Users/tony/Desktop/招聘岗位数据分析/raw_data/'+strings+'_'+str(count)+types+'page'+str(x) + '.txt','w',encoding = 'utf-8') as f:
                f.write(text)
        print('已抓取'+'第'+str(x)+'页'+'的网页信息')
        #可以写个random函数,随机间隔爬取,偷懒间隔10s一次
        time.sleep(10)


#爬取每一个标签下的网页,数据量巨大。按工作经验爬取工作经验标签下1-10页的数据,每页30条,有6个标签;一类属性有至少1.8k条记录;有exp,salary,等5个属性标签。
#input:岗位;分类标签,输入参数:类别字典、检索文字、类别url字典。
def get_all(types_list,strings,dt_url,start,end):
    for types in types_list.keys():
        get_txt(strings,types,dt_url,start,end)
        print('已抓取'+types+'类')


'''
分别是url拼接函数,某一类别下所有子项某一页的url;抓取某个类别某一页的函数;获得所有类别页面函数。
'''

爬的时候发现,网站也不是傻子,大概每爬100-200条数据,就会出现验证码,由于是初级爬虫,我也就没有去设置代理ip或者解决验证码这一问题,只能呆呆的每次手动输入验证码,然后从暂停的页面开始重新爬取;此外优化过代码以后,可以定制检索的职位信息,和爬取的初始和结束页码,也算是一种解决方法吧。


4.2解析网页

根据页面信息,想要得到的数据无非就是:岗位、薪水、位置、学历、经验、企业信息(企业名称、行业、阶段、规模)这些。用bs解析,可以得到。此外还获取了每个岗位的url详情,方便之后继续进入爬取岗位描述、职责、公司简介、岗位技能等信息。

#解析网页得到列表result0;input:lxml职位信息list
def get_list0(list0):
    result0 = []
    for item in list0:
        detail_url = 'https://www.zhipin.com'+item.find('a')['href']
        mid = item.p.contents
        #location详细程度不同,只保留主城市名字
        location = mid[0].split(' ')[0]
        experience = mid[2]
        education = mid[-1]
        #company规模
        company = item.find('div',class_='company-text').a.get_text()
        industry = item.find('div',class_='company-text').p.contents[0]
        stage = item.find('div',class_='company-text').p.contents[2]
        scale = item.find('div',class_='company-text').p.contents[-1]
        mid2 = [location,experience,education,industry,stage,scale,company,detail_url]
        result0.append(mid2)
    return result0


#解析网页得到列表item[0:2],包括岗位,薪酬
def get_list1(list1):
    result1 = []
    for item in list1:
        #最低最高岗位薪酬
        salary_scale = item[1].replace('k','').split('-')
        post = [item[0]]
        post.extend(salary_scale)
        result1.append(post)
    return result1


#得到dataframe,input:文件,output:数据框
def get_data(file):
    with open('/Users/tony/Desktop/招聘岗位数据分析/raw_data/'+file) as f:
        text = f.read()
        soup = BeautifulSoup(text,'lxml')
        list0 = soup.find_all('div',class_ = 'job-primary')
        list1 = [x.a.get_text().split('\n')[1:-2] for x in list0]
        #得到两个list
        item_info1 = get_list1(list1)
        item_info0 = get_list0(list0)
        #得到一个职位、薪酬、地点,工作经验,学历的pandas
        dt1 = pd.DataFrame(data=item_info1,columns = ['post','salary_low','salary_high'])
        dt0 = pd.DataFrame(data=item_info0,columns = ['location','experience','education','industry','stage','scale','company','detail_url'])
        result = pd.concat([dt1,dt0],axis = 1)
    return result


#得到目录下包含txt文件list
os.chdir('/Users/tony/Desktop/招聘岗位数据分析/raw_data/')
file_list = glob.glob('*.txt')


#得到某一岗位的所有信息的dataframe,input:文件名list,output:dataframe,csv
def get_dataframe(file_list):
    data = []
    for file in file_list:
        mid = get_data(file)
        data.append(mid)
    frame = data
    result = pd.concat(frame,ignore_index=True)
    result.to_csv('/Users/tony/Desktop/招聘岗位数据分析/dt_boss.csv',header=True,index=False)
    return result

以下是爬虫的结果和解析得到的结果

dt_url

Dict

正在爬取数据分析的5类标签的1-5页

清洗后的一部分结果

在得到Dataframe后,就可以对这些数据进行分析啦啦啦啦~
emm,也存在一些小问题,一不小心抓了将近2w条数据,要逐条得到详细的岗位信息,是相当漫长的过程,万恶的根源在于我这种爬虫小白,还是无法突破人家反爬的壁垒。但是这些数据已经足够进行进一步的分析啦。
此外,代码缺少通用性,这一点仍然需要改进,如果换了网页,那么又需要重新编写代码,emm,这是不是需要看一些scrapy框架来解决了呢==


补充一些中间遇到的小问题
1.刚开始用requests.get,直接报错,response 403;查询结果发现是user-agent有问题,随便找了一个常用的。
原因是默认参数不设置headers,会出现python字样,会被拒绝访问;user-agent用于隐藏自己爬虫的身份,从而访问网站。
2.在解析完页面后,想要传入文件名,如何获得某一目录下的所有文件名列表?
导入os模块,os.chdir()改需要的文件路径,os.listdir(),得到录下的所有文件,但会有一个额外文件,所以用glob.glob()来解决,获取*.txt所有文件。只负责匹配文件。
3.在浏览网页的过程中发现,鼠标移动到每条岗位信息时会出现悬浮框,如下:

岗位悬浮框

而且检查元素发现:
悬浮框代码

但是下载该页面后并无法得到这部分信息。目前想到的解决办法是模拟浏览器登录,然后模拟一系列鼠标的行为;但是仔细想来这样的步骤从打开浏览器,获取每一页每一行的信息,其速度之慢不亚于获取该岗位的详细信息的url再获取岗位信息。于是介于数据获取量之大且缓慢,放弃了该部分数据的获取:包括公司介绍、岗位表述、工作要求、基本技能等。本来该部分数据将用于文本挖掘方面的分析,就此作罢。

下一篇,我会重点对这批数据进行分析,欲知后事如何,请看下回分解~

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,271评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,275评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,151评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,550评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,553评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,559评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,924评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,580评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,826评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,578评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,661评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,363评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,940评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,926评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,156评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,872评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,391评论 2 342

推荐阅读更多精彩内容