爬虫练习-爬取拉勾网招聘信息(2020.2.2)

前言:

应对AJAX动态加载,并应用表单的交互技术,爬取爬取拉勾网招聘信息,解析网页返回的json数据,并将爬取的数据存储于MongoDB数据库中。

本文为整理代码,梳理思路,验证代码有效性——2020.2.2


环境:
Python3(Anaconda3)
PyCharm
Chrome浏览器

主要模块: 后跟括号内的为在cmd窗口安装的指令
requests(pip install requests)
pymongo(pip install pymongo )
json
time

1.

爬取目标url:https://www.lagou.com/jobs/list_python?labelWords=&fromSearch=true&suginput=
看看python的相关职位。
在这里插入图片描述

2.

在源代码中查看相关的信息,我们可以发现在网页源代码中没有找到任何岗位的信息,由此可以推断,该网页是异步加载(AJAX)的。
在这里插入图片描述

3.

打开开发者工具F12,选择Network选项,并点击XHR文件,刷新一下网页,依次查看各个文件返回的内容。
在这里插入图片描述
我们发现在第一个文件在中就返回了我们需要的信息,而且是json格式。

4.

解析json格式。由于该json格式比较复杂,所以我们先点击到Preview查看,如图。
在这里插入图片描述
那么在content —》positionResult- --》result 路径中,我们用python中的json库对其解析。
注意:这里得到的 results 是多组信息,后用循环对它进行分组拆分,详见完整代码。

html = requests.post(url, data=params, headers=headers, cookies=get_cookie(), timeout=5)

# 将网页的Html文件加载为json文件
json_data = json.loads(html.text)
# 解析json文件,后跟中括号为解析的路径
results = json_data['content']['positionResult']['result']

5.

到上一步,我们就已经获取到了信息了,但是不满足于此,我们还要爬取更多页的信息,手动翻页,发现url没有变化,可判断翻页也是异步加载,同上,我们还是进行逆向工程,去XHR文件中找线索。
发现它是一个POST请求,页数是由pn参数控制。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

6.

发现返回的json数据中含有信息的总数,如图。
在这里插入图片描述
拉勾网每页有15条岗位信息,并默认只有30页,那么我们将返回的信息总数除以15看是否小于30,若小于,总页数取对应结果,不然总页数就等于30,代码如下。

# 定义获取页数的函数
def get_page(url, params):
    html = requests.post(url, data=params, headers=headers, cookies=get_cookie(), timeout=5)

    # 将网页的Html文件加载为json文件
    json_data = json.loads(html.text)
    # 解析json文件,后跟中括号为解析的路径
    total_Count = json_data['content']['positionResult']['totalCount']

    page_number = int(total_Count/15) if int(total_Count/15) < 30 else 30

7.

爬取过程中出现如下错误,我起初同一位兄弟的想法一致,以为是headers的参数不足,各种尝试,后面把网页里的整个请求头都加进去还是没用。
在这里插入图片描述
这时有点难受了,开始百度,发现请求要添加相应的Cooke值才行,但是拉钩网的的Cookie内含时间戳,即具有一次性,于是用下面的代码获取cookie完美解决问题。

# 获取cookies值
def get_cookie():
    # 原始网页的URL
    url = "https://www.lagou.com/jobs/list_python?labelWords=&fromSearch=true&suginput="
    s = requests.Session()
    s.get(url, headers=headers, timeout=3)  # 请求首页获取cookies
    cookie = s.cookies  # 为此次获取的cookies
    return cookie

参考资料,请移步至页尾查看123


完整代码

# 导入相应的文件
import requests
import json
import time
import pymongo

# 连接数据库
client = pymongo.MongoClient('localhost', 27017)

# 创建数据库和数据集合
mydb = client['mydb']
lagou = mydb['lagou']

# 加入请求头
headers = {
    "Accept": "application/json, text/javascript, */*; q=0.01",
    "Referer": "https://www.lagou.com/jobs/list_python?labelWords=&fromSearch=true&suginput=",
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 "
                  "(KHTML, like Gecko) Chrome/79.0.3945.130 Safari/537.36",
}


# 获取cookies值
def get_cookie():
    # 原始网页的URL
    url = "https://www.lagou.com/jobs/list_python?labelWords=&fromSearch=true&suginput="
    s = requests.Session()
    s.get(url, headers=headers, timeout=3)  # 请求首页获取cookies
    cookie = s.cookies  # 为此次获取的cookies
    return cookie


# 定义获取页数的函数
def get_page(url, params):
    html = requests.post(url, data=params, headers=headers, cookies=get_cookie(), timeout=5)

    # 将网页的Html文件加载为json文件
    json_data = json.loads(html.text)
    # 解析json文件,后跟中括号为解析的路径
    total_Count = json_data['content']['positionResult']['totalCount']

    page_number = int(total_Count/15) if int(total_Count/15) < 30 else 30

    # 调用get_info函数,传入url和页数
    get_info(url, page_number)


# 定义获取招聘信息函数
def get_info(url, page):
    for pn in range(1, page+1):
        # post请求参数
        params = {
            "first": "true",
            "pn": str(pn),
            "kd": "python"
        }

        # 获取信息 并捕获异常
        try:
            html = requests.post(url, data=params, headers=headers, cookies=get_cookie(), timeout=5)
            print(url, html.status_code)
            # 将网页的Html文件加载为json文件
            json_data = json.loads(html.text)
            # 解析json文件,后跟中括号为解析的路径
            results = json_data['content']['positionResult']['result']

            for result in results:
                infos = {

                    # positionName: "python"
                    #
                    # companyFullName: "深圳云安宝科技有限公司"
                    # companySize: "15-50人"
                    # industryField: "信息安全,数据服务"
                    # financeStage: "A轮"
                    #
                    # firstType: "开发|测试|运维类"
                    # secondType: "后端开发"
                    # thirdType: "Python"
                    #
                    # positionLables: ["云计算", "大数据"]
                    #
                    # createTime: "2020-02-02 12:51:01"
                    #
                    # city: "深圳"
                    # district: "南山区"
                    # businessZones: ["科技园"]
                    #
                    # salary: "15k-30k"
                    # workYear: "3-5年"
                    # jobNature: "全职"
                    # education: "本科"
                    #
                    # positionAdvantage: "地铁口近 周末双休"
                    
                    "positionName": result["positionName"],

                    "companyFullName": result["companyFullName"],
                    "companySize": result["companySize"],
                    "industryField": result["industryField"],
                    "financeStage": result["financeStage"],

                    "firstType": result["firstType"],
                    "secondType": result["secondType"],
                    "thirdType": result["thirdType"],

                    "positionLables": result["positionLables"],

                    "createTime": result["createTime"],

                    "city": result["city"],
                    "district": result["district"],
                    "businessZones": result["businessZones"],

                    "salary": result["salary"],
                    "workYear": result["workYear"],
                    "jobNature": result["jobNature"],
                    "education": result["education"],

                    "positionAdvantage": result["positionAdvantage"]
                }
                print(infos)
                # 插入数据库
                lagou.insert_one(infos)
                # 睡眠2秒
                time.sleep(2)
        except requests.exceptions.ConnectionError:
            print("requests.exceptions.ConnectionError")
            pass


# 主程序入口
if __name__ == '__main__':
    url = "https://www.lagou.com/jobs/positionAjax.json"
    # post请求参数
    params = {
        "first": "true",
        "pn": 1,
        "kd": "python"
    }
    get_page(url, params)

  1. 获取cookie的方法 ↩︎

  2. 指出拉勾网的Cookie具有时间戳,一次性 ↩︎

  3. 后知后觉,获取Cookie的url为原始请求的URL ↩︎

  • 12
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 14
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 14
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值