053_爬虫案例_拉勾网职位需求采集

需求分析

知己知彼,方可百战不殆。在学习技术的时候我们往往面临太多选择而不知所措,可能是各个方面都有涉猎,对某个领域没有深入研究,看似什么都会,真要让你做个什么东西的时候就显得捉肘见襟。如果我们能从招聘职位所需的技能开始学习,便可练就一身硬功夫,为实战应用中打下良好的基础。

通过python抓取拉钩网的招聘详情,并筛选其中的技能关键词,存储到excel 中。

项目简介
职位检索页面分析

通过对职位检索页面分析发现需要的职位信息在content –> positionResult –> result 下,其中包含了工作地点、公司名、职位等信息。 我们只需要保存这个数据 (JSON格式) 就可以了。
在这里插入图片描述
真实的URL获取
需要注意:在职位检索过程中真正请求的url地址是https://www.lagou.com/jobs/positionAjax.json?needAddtionalResult=false
在这里插入图片描述

职位详情页面分析

点击进入具体的职业招聘信息的详情页

  • 通过观察可以发现,拉勾网的职位页面详情是由 http://www.lagou.com/jobs/
    positionId.html 组成。
    在这里插入图片描述
    注意:
  • 拉勾网反爬虫做的比较严,请求头可多添加几个参数才能不被网站识别。反爬报错一般如下所示:
    在这里插入图片描述
  • 找到真正的请求网址,发现返回的是一个JSON 串,解析这个JSON 串即可,而且注意是POST传值,通过改变Form Datapn 的值来控制翻页。
    在这里插入图片描述
  • XHRXMLHttpRequest 对象用于和服务器交换数据。

点击页面中的页数,比如第 2 页,我们可以在右边看到一个 POST 请求,这个请求里面包含了真实的 URL (浏览器上的URL 并没有职位数据,查看源代码就可以发现这一点)、POST 请求的请求头Headers 、POST 请求提交的表单Form Data (这里面包含了页面信息pn 、搜索的职位信息kd)

代码示例:

import time

import requests
from fake_useragent import UserAgent
from lxml import etree

ua = UserAgent()


def download_positions(kd="python", city="北京", page=1):
    """
    获取拉勾网所有的岗位API接口的响应信息
    :param kd: 岗位名称/关键字
    :param city: 城市
    :param page: 页码
    :return: position_id
    """
    # 拉勾网访问的网址,并不是Ajax的网址
    # old_url = 'https://www.lagou.com/jobs/list_python'
    # 真实的API接口的网址(通过F12开发者模式中的XHR分析出来的)
    url = 'https://www.lagou.com/jobs/positionAjax.json?=false'
    # url提交的参数信息, http://xxxxx/?param1=value1&param2=value2
    params = {
        'city': city,
        # 'needAddtionalResult': 'false',
    }
    # url以POST方式提交的信息(参数分析出来的)
    data = {
        # 'first': 'true',
        'pn': page,
        'kd': kd
    }
    # 头部信息, 为了防止拉钩反爬策略的
    headers = {
        'UserAgent': ua.random,
        'Host': 'www.lagou.com',
        'Origin': 'https://www.lagou.com',
        'Referer': 'https://www.lagou.com/jobs/list_python',
        'TE': 'Trailers',
        'X-Requested-With': 'XMLHttpRequest',
        'Connection': 'keep-alive',
        'Accept': 'application/json, text/javascript, */*; q=0.01',
        'Accept - Encoding': 'gzip, deflate, br',
        'Accept-Language': 'zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2',
    }

    # 以POST方式请求网址并返回响应
    response = requests.post(url=url, params=params, data=data)
    data = response.json()
    print(data)

    if data.get('status') == False:
        raise Exception("获取职位失败: %s" % (response.text))
    else:
        return response


def parse_position_ids(response):
    """
    根据页面信息解析所有岗位的ID号
    :param response:
    :return: 字典
    """
    # 响应的信息是json格式, 通过json方法自动化解析json字符串为python对象
    ajax_data = response.json()
    content = ajax_data.get('content')
    positionResults = content.get('positionResult').get('result')
    for position in positionResults:
        yield {
            'name': position.get('positionName'),
            'positionId': position.get('positionId')
        }


def download_detail(id):
    """下载详情页页面"""
    url = 'https://www.lagou.com/jobs/%s.html' % (id)
    try:
        response = requests.get(url)
    except Exception as e:
        print("采集职位详情页失败: " % (str(e)))
    else:
        return response


def parse_position_detail(id):
    """解析详情页页面并提取岗位详情内容"""
    response = download_detail(id)
    # 使用解析器解析页面的岗位详情(正则、Xpath、BS4)
    html = etree.HTML(response.text)
    # 通过类名寻找class="job-detail"的节点, xpath('string(.)')获取节点所有的文本信息(标签自动删除)
    job_detail = html.xpath('//div[@class="job-detail"]')
    if job_detail:
        return job_detail[0].xpath('string(.)')
    return job_detail[0]


def test_ids():
    response = download_positions()
    position_ids = parse_position_ids(response)
    for id in position_ids:
        print(id)


def test_detail_id():
    id = '6372641'
    job_detail = parse_position_detail(id)
    print(job_detail)


if __name__ == '__main__':
    test_ids()
    test_detail_id()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值