拉勾网数据两种爬取

作者: 可乐还是百事好 | 来源:发表于2018-10-14 22:35 被阅读55次

写在前面:

拉勾网数据爬取是一个蛮经典的爬虫案例 ,由于被频繁被爬取的原因 ,网站经过不断更新 ,加入了一些反爬技术 。例如:参数的加密 、AJAX异步加载JSON数据 。对于入门爬虫的新手来说 ,还是有一些困难 。这里用到selenium和post请求两种方式解析网页 ,希望可以帮到你们 。

分析网页:

这里我们以 数据分析 该职位为例 : 链接
数据在网页一般会分为两种加载方式 : 在原网页内与不在原网页内 。判断的方法可以复制网页内要爬取的一些数据 ,然后右击网页 ——查看源代码 , 看一看是否可以找到 。:

picture_1
按ctrl + f 输入复制的的数据发现并没有存在原网页内 。
那么可以推断出 , 我们要爬取的数据是通过AJAX异步加载JSON数据到网页的 。
那我们需要在网页后台找到那个json数据 ,我用的是chrom浏览器 ,右击 ——检查 :
picture_2
在picture_1中 选择 network --- XHR (如果没有数据的话,重新加载一下网页) ,可以在左边看到四个json链接 。因为我们要爬取的是职位 ,很快我们就可以确定目标url ,picture_3验证了准确性 :
picture_3
在picture_3中我们可以很清楚的看见这是一个json格式的数据 ,通过分析 ,可以找到数据在result下面 : picture_4
通过对比picture_5发现就是我们要爬取的数据 。
picture_5

编写爬虫:

https://www.lagou.com/jobs/positionAjax.json?px=default&city=%E8%8B%8F%E5%B7%9E&needAddtionalResult=false
我们要解析的url在Headers中可以看出是post请求 。

picture_6
下面我们构造headers :
my_headers = {
            'User-Agent':'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36',
            'Host':'www.lagou.com',
            'Referer':'https://www.lagou.com/jobs/list_{}?labelWords=sug&fromSearch=true&suginput='.format(position_id),
            'X-Anit-Forge-Code':'0',
            'X-Anit-Forge-Token': 'None',
            'X-Requested-With':'XMLHttpRequest'
            }

其中的referer可以看到 ,我用format函数加入了一个参数 ,便于爬取不同城市的数据 , 如果你只打算爬取一个城市这里可以不加 ,只使用浏览器上带的参数 。
提交的 data:

my_data = {
            'first': 'true',
            'pn':num,
            'kd':position
}
picture_7

从picture中可以看出需要post数据主要有三个 ,其中 pn:为页码数 ,kd:为职位名称 。因此 ,我将这两个参数的值设置为变量 num和position ,便于接下来的post页码和不同职位的实现 。

def get_json(url,num,position,position_id):
    #print(position)
    
    '''''从网页获取JSON,使用POST请求,加上头部信息'''
    my_headers = {
            'User-Agent':'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36',
            'Host':'www.lagou.com',
            'Referer':'https://www.lagou.com/jobs/list_{}?labelWords=sug&fromSearch=true&suginput='.format(position_id),
            'X-Anit-Forge-Code':'0',
            'X-Anit-Forge-Token': 'None',
            'X-Requested-With':'XMLHttpRequest'
            }

    my_data = {
            'first': 'true',
            'pn':num,
            'kd':position}

    res = requests.post(url, headers = my_headers, data = my_data)
    res.raise_for_status()
    res.encoding = 'utf-8'
    # 得到包含职位信息的字典
    page = res.json()
    return page

这是带headers和data完整的post请求 , 其中函数由四个参数 ,url为刚刚我们找出的那个链接 。num是页码 ,这里我们先设置为起始页码1 。position为职位名称 ,position_id为职位代号 。我们可以从headers的referen中看出 :https://www.lagou.com/jobs/list_%E6%95%B0%E6%8D%AE%E5%88%86%E6%9E%90?labelWords=sug&fromSearch=true&suginput=shujufenxi 在list_到?中的职位名称被加密出现, 所以我构造了一个字典 :

def getCity():
        return [
            
            {"苏州":"%E8%8B%8F%E5%B7%9E"},
            {"深圳":"%E6%B7%B1%E5%9C%B3"},
            {"上海":"%E4%B8%8A%E6%B5%B7"},
            {"杭州":"%E6%9D%AD%E5%B7%9E"},
            {"南京":"%E5%8D%97%E4%BA%AC"},
        ]

def getLanguage():
        return [
            #"python",
            {"数据分析":"%E6%95%B0%E6%8D%AE%E5%88%86%E6%9E%90"},
            {"图像处理":"%E5%9B%BE%E5%83%8F%E5%A4%84%E7%90%86"},
            {"":""},
            {"":""},
            {"":""},


        ]

将需要爬取的城市 、职位所对应的加密码一一对应 。
get_json函数返回了json数据 ,包括了职位总数 ,这样我们就可以构造一个函数 ,而且拉勾网 一页最多显示15个职位 ,计算出我们爬取职位的总页数了 。


def get_page_num(count):
    '''''计算要抓取的页数'''
    # 每页15个职位,向上取整
    res = math.ceil(count/15)
    # 拉勾网最多显示30页结果
    if res > 30:
        return 30
    else:
        return res

计算出页数之后 , 我们就可以通过一个循环 ,带着可变参数反复post数据:

for n in range(1,num+1):

        # 对每个网页读取JSON, 获取每页数据
        page = get_json(url,n,position,position_id)
        try:
            jobs_list = page['content']['positionResult']['result']
        except:
            continue
            
        page_info = get_info_to_mongodb(jobs_list)
        res_list.extend(page_info)

查看返回的结果 ,这里我通过构造一个含有dict的list便于存入mongodb ,看个人需求 :

picture_8.png picture_9.png

通过看原网页的数据 , 我们发现数据已经被爬取先来了 一共19个职位 ,共分两页

相关文章

网友评论

本文标题:拉勾网数据两种爬取

本文链接:https://www.haomeiwen.com/subject/btiyaftx.html