AI算法工程师岗位分析Part I 使用Python实现数据采集


欢迎转载,vmfor.com ©版权所有, 转载须注明出处,并带有文末二维码

作者:GavinHacker

现在AI非常火,最近使用[机器学习]的关键字,搜集了一下智联上的关于机器学习的工作岗位,数据总量是5753个,针对不同城市,包括一线城市和二三线城市,做了一下工作数量统计,如下:

image

(这张图有点丑,是通过数据库查询工具直接查的...)

报表工具的图如下:

image

image

工作地点和岗位的占比饼图

image

岗位要求中的不同学历占比

image

工作经验的占比

image

工作职位的占比(有的软件工程师也要求有机器学习经验)

image

以上是简单的一些数据分析。

下面介绍一下数据采集。

这次采集,使用的是Python语言,主要是针对智联招聘网站的网页抓取。URL地址:

dy_url = 'http://sou.zhaopin.com/jobs/searchresult.ashx?jl={0}&kw=机器学习&isadv=0&sg=44ecf616b90f490e833f333f077711f1&p={1}'

我对以下城市进行了数据抓取:

A = ['上海','北京','广州','深圳']
B = ['重庆','天津','杭州','南京','武汉','沈阳','济南','长春','哈尔滨','石家庄', '长沙','成都','西安','昆明','郑州','福州','南昌','合肥','乌鲁木齐','大连','青岛']
C = ['太原','呼和浩特','贵阳','兰州','海口','宁波','温州','厦门','大庆','珠海','中山','东莞','台州','泉州','汕头','无锡','苏州','徐州','湖州','湛江','烟台','淄博','潍坊','济宁','唐山','保定','大同','吉林','鞍山','齐齐哈尔','包头','柳州','株洲','南宁', '常德','洛阳','宜昌','绵阳','襄樊','荆州','南阳']

# 对每一个工作索引页进行处理
def acquire_(url):
    try:
        response = s.post(url, headers = header)
        content = beaut_soup(response.content, "html.parser")
        sub_table_content =  content.find_all(id='newlist_list_content_table')
        for sub_item in beaut_soup(sub_table_content.__str__(), "html.parser").find_all(attrs={"class" : "zwmc"}):
            for a in beaut_soup(sub_item.__str__(), 'html.parser').find_all('a'):
                job_url = a.get('href', 'none')
                print job_url
                parse_per_job(s, job_url)

        print response.status_code
    except BaseException as ce:
        print 'Acquire exception:', ce

> 我们使用智联的时候,搜索结果页面,通过处理,得到每个工作的具体信息页面链接,然后再爬取每个得到的链接



# 解析每一个招聘信息页面, 函数内包含对html标签的一些查询操作,使用的是beautiful soup库
def parse_per_job(session, job_url):
    try:
        if exist(job_url):
            print 'exist url' , job_url
            return
        response = session.post(job_url, headers = header)
        content = beaut_soup(response.content, "html.parser")

       #这里模仿human操作,间隔随即时间再爬去下一个页面,不过还是人家智联不反扒,否则这个简单操作不好使的
       time.sleep(random.randint(1,10))
        data_set = set()
        for x in content.find_all(attrs={"class":"terminal-ul clearfix"}):
            features = beaut_soup(x.__str__(), 'html.parser').find_all('li')
            for feature in features:
                #print feature.span.text,
                feature_tup = get_feature_value(feature.span.text, feature)
                print feature_tup[0], feature_tup[2]
                data_set.add((feature_tup[1], "'"+feature_tup[2] + "'"))
        for x in content.find_all(attrs={"class":"terminalpage-main clearfix"}):
            #print x
            html_data = {'data': x.__str__()}
            data_set.add((tup_invite_des[1], "'" + base64.b64encode(x.__str__()) + "'"))
            break
        data_set.add(('url', "'" + job_url + "'"))
        print '+--------------------------+'
        # keys = ""
        # values = ""
        # for r in data_set:
        #     keys = keys + ',' + r[0].__str__()
        #     values = values + r[1].__str__()
        prepared_record = reduce(lambda x, y: (x[0].__str__() + ',' + y[0].__str__(), x[1].__str__() + ',' + y[1].__str__()), data_set)
        #prepared_record = reduce(lambda x, y: (x[0].__str__() + ',' + y[0].__str__(), (x[1].__str__(),) + (y[1].__str__(),)), data_set)
        print prepared_record
        if exist(job_url):
            print 'exist url, insert by other agent' , job_url
        else:
            insert_record(prepared_record[0], prepared_record[1])
        #print '(' + keys + ')', '(' + values + ')'
        print '+--------------------------+'
    except Exception as e:
        print e

# 将采集到的工作岗位数据插入数据库
def insert_record(keys, values):
    sql = "INSERT INTO `zl` ({0}) VALUES ({1})".format(keys, values)
    print sql
    cursor = connection.cursor()
    cursor.execute(sql)
    connection.commit()

# 判断该条数据是否已经采集过
def exist(key):
    sql = "select count(*) as cnt from zl where url = %s"
    cursor = connection.cursor()
    cursor.execute(sql, key)
    connection.commit()
    result = cursor.fetchone()
    return result['cnt']

# 页面字段和数据库表存储字段
tup_url = ('url', 'url')
tup_salary = ('职位月薪', 'salary')
tup_work_city = ('工作地点', 'work_city')
tup_publish_time = ('发布日期', 'publish_time')
tup_work_type = ('职位类别', 'work_type')
tup_work_way = ('工作性质', 'work_way')
tup_work_exp = ('工作经验', 'work_exp')
tup_work_edu = ('最低学历', 'education')
tup_invite_cnt = ('招聘人数', 'invite_count')
tup_invite_des = ('工作描述', 'description')

这里没有进一步的解析岗位要求的数据,而是把整个岗位要求的html代码压缩存了起来,通过创建web服务的方式可以根据具体id(url)查看岗位描述,不过这不妨碍下一步的分析,只要把相对原始的数据存起来就好了,之后用的时候再根据需求解析。

第一篇介绍到这里,后续我准备对技能描述-工资-经验 =>工资 进行进一步的进阶分析,我会把涉及到的代码整理的更简洁易读,上传到github上,作为自己学习的一个记录,也和大家一起分享和交流。

关注vmfor.com , 一起交流AI技术

image