招聘网站分析-智联招聘网的爬虫设计与实现

爬虫文件

原理

1、分析
智联招聘网是招聘网站中爬取难度最高的网站。为了减轻爬虫对网站运营的影响,要求用户必须注册登录,否则提示登录后才能进行信息检索。
智联招聘网的页面布局以及列表页请求url。注册登录后,职位搜索列表页和详情页如图1、图2所示。
在这里插入图片描述

图1 智联招聘网职位搜索列表页
在这里插入图片描述

图2智联招聘网职位搜索详情页
2.爬虫数据存储设计
对于爬虫来说,最重要的是爬取下来的数据,所以爬虫项目在开发前需要考虑数据的保存格式以及保存的数据项。前期预估网站爬取的数据在 10 万以内,数据量较小,所以考虑采用 CSV 等文本格式或 MySQL 数据库进行存储。
如果采用 CSV 文本格式进行存储,在数据清洗前还要考虑数据合并。
结合需求分析中的数据分析目标,分析前程无忧、猎聘网、智联招聘三个招聘网站的岗位的数据,确定数据采集项。利用数据库中的表结构设计形式进行展示每个数据项的含义及作用。
最后进行数据库设计,在mysql数据库实现表的创建。
内容:
1.分析招聘网站每条招聘信息的内容,确定爬虫数据项,以数据库表结构形式进行展示。
2.确定数据存储格式,在scrapy项目中编写数据存储的相关代码。

页面分析

按要求完成注册后,正常情况下输入用户名和密码后可以直接登录。如果被网站识别为异常登录或频繁登录会出现拼图验证码,直接就提升了我们爬虫编写的难度。智联招聘网的拼图验证码调用的是第三方的API,破解难度较大。也就是意味着通过代码实现模拟登录并破解拼图验证码的代价较大。
进一步思考,HTTP协议是无状态的协议,如果要实现状态保持势必要用到Session或Cookies,Session又是基于Cookies实现的。通俗的讲,网站判定用户是否登录,是基于客户端发送请求时是否传递Cookies来进行验证的。也就是说我们可以人为进行网站登录,然后通过程序代码读取网站生成的Cookies,在发送请求时传递Cookies,这样就可以通过登录验证,从而降低爬虫编写的难度。由于Cookie有时间限制,也就意味着启动爬虫前最好重新进行登录。
打开浏览器开发者工具,切换到“Network”,在列表页的搜索框中输入检索关键字,点击“搜索”图标。选择“XHR”或“Doc”查看拦截到的请求。如图3所示。
在这里插入图片描述
图3 智联招聘网职位搜索API接口
点击“Preview”,观察响应数据,如图4所示。可以看出响应数据为json格式。
在这里插入图片描述
2.爬虫编写
Cookies的获取是智联招聘网爬虫中最核心的内容。Cookies在不同浏览器下数据格式是不同的,IE浏览器的Cookies是一个一个的txt文件,Chrome浏览器是将所有的Cookies
保存在本地SQLite数据库中。由于我们的解决方案只针对windows下的Chrome浏览器,无法兼容其他浏览器,所以把“Cookies获取”这段Python程序代码单独封装为class。
Scrapy项目创建后,在item.py同级目录下创建CookieUtils.py文件。程序实现的基本思路为查询C:\Users\用户\AppData\Local\Google\Chrome\UserData\Default\Cookies下SQLite数据库中指定domain的Cookie键和值,解密后以字典形式返回。由于调用windows API,所以需要安装第三方库pywin32。SQLite为Python标准库不需要安装。
首页路由:
在这里插入图片描述
详细页路由:
在这里插入图片描述
由于涉及反爬机制,需要cookie
CookieUtils.py

import os
import json
import base64
import sqlite3
from win32crypt import CryptUnprotectData
from cryptography.hazmat.primitives.ciphers.aead import AESGCM
#读取local state文件的加密key
def get_string(local_state):
    with open(local_state, 'r', encoding='utf-8') as f:
        s = json.load(f)['os_crypt']['encrypted_key']
    return s
#导出解密密钥
def pull_the_key(base64_encrypted_key):
    encrypted_key_with_header = base64.b64decode(base64_encrypted_key)
    encrypted_key = encrypted_key_with_header[5:]
    key = CryptUnprotectData(encrypted_key, None, None, None, 0)[1]
    return key
#aes解密
def decrypt_string(key, data):
    nonce, cipherbytes = data[3:15], data[15:]
    aesgcm = AESGCM(key)
    plainbytes = aesgcm.decrypt(nonce, cipherbytes, None)
    plaintext = plainbytes.decode('utf-8')
    return plaintext
#获取cookie函数入口,参数host为域名
def get_cookie_from_chrome(host='%.zhaopin.com'):
#chrome浏览器配置文件Local State路径
    local_state = os.environ['LOCALAPPDATA'] + \
                  r'\Google\Chrome\User Data\Local State'
    cookie_path = os.environ['LOCALAPPDATA'] + \
                  r"\Google\Chrome\User Data\Default\Cookies" #cookie的本机路径
#sqlite数据库,cookies表查询语句,模糊匹配
    sql = "select host_key,name,encrypted_value " \
                     "from cookies where host_key like '%s'" % host
    with sqlite3.connect(cookie_path) as conn: #创建数据库连接
        cu = conn.cursor()   #打开游标
        res = cu.execute(sql).fetchall() #获取所有数据
        cu.close() #关闭游标
        cookies = {}
        key = pull_the_key(get_string(local_state)) #读取密钥
#将解密的数据转换为字典
        for host_key, name, encrypted_value in res:
            if encrypted_value[0:3] == b'v10':
                cookies[name] = decrypt_string(key, encrypted_value)
            else:
                cookies[name] = CryptUnprotectData(encrypted_value)[1].decode()
        cookies_str = ""
        for item in cookies:
            cookies_str +="%s=%s;" %(item,cookies[item])
        return cookies_str

# print(get_cookie_from_chrome())

json格式数据的获取:
参考详细解析
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

数据库展示

在这里插入图片描述

后续可能需要数据清洗,还没写,,,后面应该会补充

猜你喜欢

转载自blog.csdn.net/weixin_45044349/article/details/118767294