使用scrapy框架爬取腾讯招聘的岗位

news/2024/7/19 8:40:32 标签: python, 爬虫, scrapy

本篇将介绍使用scrapy爬取动态加载网站的方法,这样的网站我们很常见,我们这次就是爬取腾讯招聘的岗位数据

我们爬取的是这个页面里的岗位数据
在这里插入图片描述
点进去后是显示的是所有的岗位,我们想要什么岗位就直接搜就可以

在这里插入图片描述
比如我们搜一个python方面的岗位吧,(此时出现的页面就是一级页面),但是呢,这些岗位的数据都是不全的,有工作职责,但是没有具体的工作要求,比如要求几年以上的工作经验,要什么学历等等

在这里插入图片描述
所以我们一级页面也不知要抓什么,但是我要抓取每个职位的信息,我们要到详情页里面去找,随便点击进一个职位看一下
在这里插入图片描述
我们找到了有效的数据了,这个里面的数据就全了

第一个就是岗位名字,第二个是地点,第三个岗位的类型,是技术,是销售等等,第四个发布时间,第五个工作职责,第六个工作要求
因为 这样的网站是动态加载的,所以我们在一级页面直接F12抓包,刷新一下,顺带手的点击下一页,我们直接进入到XHR
先点击一个数据包看一下

在这里插入图片描述
这个应该不是,它应该是上面的那些个过滤条件
我们接着看下面这个
在这里插入图片描述
这个应该是了,虽然也没有具体的工作要求,但是大体的数据还是我们需要的,那我们到headers里面看看

这个是一个GET请求,查询的参数略微的有点多

在这里插入图片描述
在来看一下查询参数,大概有这些
在这里插入图片描述
第一个就是一个13位的时间戳,下面空的没参数的就是筛选条件,再下面keyword就是输入的关键字,是什么岗位,pageIndex这个是变得,就是页数,pageSize是一页有10个职位,这样还好,里面的问题也不是太大,唯一一个有问题的就是那个时间戳

上面Headers里面的URL地址就是json地址,我们复制放到浏览器地址栏里面看看是什么样子的

在这里插入图片描述
这些就是json数据,这就是一级页面,但是到现在一级页面到底抓什么我们还是不太清楚,那我们接下来看一下二级页面

同样我们也是抓包

在这里插入图片描述

第一个数据包就是职位信息,这里面就有我们要抓的那六个信息,接着到Headers里面分析一下,同样是GET请求,我们还是看查询参数

在这里插入图片描述

这个里面第一个还是个时间戳,第二个是职位id,这个每个职位和每个职位是不一样的,第三个就是语言,现在的问题是职位id没有搞定,时间戳还是挺好搞定的

那我们看这个二级页面网络数据包中也找不到其他的数据包的职位ID了,我们想要所有职位的id,我们只能从一级页面中找所有的postId只要一级页面中提取一页10个postId,那我们就可以拼接10个二级页面详情页的json地址了

那我们就去一级页面中找看有没有postId

在这里插入图片描述
一级页面显示他是有的,且每个都不一样,好了,现在我们只需要做的就是想办法拼接postId和二级页面的URL地址了

我先把二级页面的URL地址用浏览器打开放着
在这里插入图片描述

在这里插入图片描述

好接下来我们就正式去写代码了
首先还是创建爬虫项目以及爬虫文件,这里我就不啰嗦了,直接写代码了

items.py文件

python"># -*- coding: utf-8 -*-

# Define here the models for your scraped items
#
# See documentation in:
# https://docs.scrapy.org/en/latest/topics/items.html

import scrapy


class TencentItem(scrapy.Item):
    # define the fields for your item here like:
    # 定义爬取字段
    job_id = scrapy.Field()
    job_name = scrapy.Field()
    job_type = scrapy.Field()
    job_city = scrapy.Field()
    job_time = scrapy.Field()
    job_require = scrapy.Field()
    job_duty = scrapy.Field()

tencent.py爬虫文件

python"># -*- coding: utf-8 -*-
import scrapy
# 分析时间戳用
import time
# 编码
from urllib import parse
import json

from ..items import TencentItem


class TencentSpider(scrapy.Spider):
    name = 'tencent'
    allowed_domains = ['careers.tencent.com']
    # 一级页面url地址
    one_url = 'https://careers.tencent.com/tencentcareer/api/post/Query?timestamp={}&countryId=&cityId=&bgIds=&productId=&categoryId=&parentCategoryId=&attrId=&keyword={}&pageIndex={}&pageSize=10&language=zh-cn&area=cn'
    # 二级页面url地址
    two_url = 'https://careers.tencent.com/tencentcareer/api/post/ByPostId?timestamp={}&postId={}&language=zh-cn'

    # 拼接第一页的url地址,首先要搞定一级页面的三个变量,即 timestamp keyword pageIndex
    keyword = input('请输入职位类别:')
    keyword = parse.quote(keyword)
    # start_urls: 一级页面第1页的URL地址
    start_urls = [one_url.format(int(time.time() * 1000), keyword, 1)]

    def parse(self, response):
        """生成所有一级页面的url地址,交给调度器入队列"""
        # 获取总页数
        html = json.loads(response.text)
        count = html['Data']['Count']
        total = count // 10 if count % 10 == 0 else count // 10 + 1
        # 生成所有页的url地址
        for index in range(1, total + 1):
            page_url = self.one_url.format(int(time.time() * 1000),
                                           self.keyword,
                                           index)
            # 调度器入队列
            yield scrapy.Request(url=page_url, callback=self.detail_page)

    def detail_page(self, response):
        """一级页面:提取每个职位的postId的值"""
        html = json.loads(response.text)
        for one_job_dict in html['Data']['Posts']:
            item = TencentItem()
            item['job_id'] = one_job_dict['PostId']
            # 生成详情页的URL地址,交给调度器入队列
            url = self.two_url.format(int(time.time() * 1000), item['job_id'])
            # meta参数:在不同解析函数之间传递数据
            # meta字典先到调度器,再到下载器,meta会作为response的一个属性,传递个下一个解析函数
            #
            yield scrapy.Request(url=url, meta={'item': item}, callback=self.get_job_info)

    def get_job_info(self, response):
        """二级页面:提取每个职位的信息"""
        html = json.loads(response.text)
        item = response.meta['item']
        item['job_name'] = html['Data']['RecruitPostName']
        item['job_type'] = html['Data']['CategoryName']
        item['job_city'] = html['Data']['LocationName']
        item['job_time'] = html['Data']['LastUpdateTime']
        item['job_require'] = html['Data']['Requirement']
        item['job_duty'] = html['Data']['Responsibility']
        # 数据提取完成,现在交给管道文件
        yield item

写管道文件之前呢,要先把数据库整理好,我这里给出一份样本,可供参考,进入数据库后,直接复制粘题即可

python">create database tencentdb charset utf8;
use tencentdb;
create table tencenttab(
job_id varchar(100),
job_name varchar(500),
job_type varchar(500),
job_city varchar(200),
job_time varchar(200),
job_require varchar(5000),
job_duty varchar(5000)
)charset=utf8;

pipelines.py管道文件

python"># -*- coding: utf-8 -*-

# Define your item pipelines here
#
# Don't forget to add your pipeline to the ITEM_PIPELINES setting
# See: https://docs.scrapy.org/en/latest/topics/item-pipeline.html


class TencentPipeline(object):
    def process_item(self, item, spider):
        print(dict(item))
        return item


import pymysql


class TencentMysqlPipeline(object):
    def open_spider(self, spider):
        self.db = pymysql.connect('localhost', 'root', '123456', 'tencentdb', charset='utf8')
        self.cur = self.db.cursor()
        self.ins = 'insert into tencenttab values(%s,%s,%s,%s,%s,%s,%s)'

    def process_item(self, item, spider):
        li = [
            item['job_id'],
            item['job_name'],
            item['job_type'],
            item['job_city'],
            item['job_time'],
            item['job_require'],
            item['job_duty'],
        ]
        self.cur.execute(self.ins, li)
        self.db.commit()
        return item

    def close_spider(self, spider):
        self.cur.close()
        self.db.close()

setting.py全剧配置文件

python">ROBOTSTXT_OBEY = False
DOWNLOAD_DELAY = 1
DEFAULT_REQUEST_HEADERS = {
    'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
    'Accept-Language': 'en',
    'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.116 Safari/537.36',
}
ITEM_PIPELINES = {
    'Tencent.pipelines.TencentPipeline': 300,
    'Tencent.pipelines.TencentMysqlPipeline': 200,
}

run.py文件

python">from scrapy import cmdline

cmdline.execute('scrapy crawl tencent'.split())

http://www.niftyadmin.cn/n/835409.html

相关文章

照片尺寸大小怎样换算?

这次简要学习一下照片的单位换算! 照片的尺寸是以英寸为单位的,1英寸2.54cm 。 我理解的我们通常所说的多少寸是这样来的: 1.英寸单位的宽*高,有整数有小数,按照整数来叫,比如1寸的是1*1.5inch,…

ubuntu上安装curl后无法使用

今天准备在我的ubuntu上安装curl玩一玩,在ubuntu上安装curl可以参考:curl 安装安装成功之后,我使用:curl --version复制代码判断curl是否安装成功时,发现报错,curl无法使用:解决方法&#xff1a…

Python下使用 redis数据库

初识Rdeis数据库 简介 redis是一个key-value存储系统。和Memcached类似,它支持存储的value类型相对更多,包括string(字符串)、list(链表)、set(集合)、zset(sorted set --有序集合)和hash(哈希类型)。这些数据类型都支持push/pop、…

分 布 式 机 房 监 控 开 发 平 台--总 体 设 计 方 案

分 布 式 机 房 监 控 开 发 平 台--总 体 设 计 方 案 1概述 1.1项目背景 该系统是对原广电机房监控系统的升级,由原来的B/S架构,升级为C/S架构,并新增了平面图显示模块以及将配置模块从整个系统中分离出来,而且,整个…

听说你想面对监狱编程,你,够格吗?

先说明一下,我的这篇文章没有太多的技术含量,最多只有一些的技术总结,剩下的是我这几个月算是自身经历吧,但是没跑题啊,还是跟爬虫技术的先关的,不喜欢可以关了哈,来都来了就看看呗,…

Flink1.7.2 DataStream Operator 示例

Flink1.7.2 DataStream Operator 示例 源码 https://github.com/opensourceteams/flink-maven-scalahttps://github.com/opensourceteams/flink-maven-scala/tree/master/src/main/scala/com/opensourceteams/module/bigdata/flink/example/datastream/operatormap 处理所有元素…

5G一周热闻:华为夺联通5G大单,首张5G电话卡发放

2019年,5G的发展步伐越来越快,大小新闻不断。美国第四大运营商Sprint起诉第二大运营商AT\u0026amp;T,声称后者使用虚假5G标签误导消费者一事让市场冷静了不少。回归到实践层面,国内三大运营商一直在寻求5G测试场景,并积…

界面无小事(八):RecyclerView增删item

界面无小事(一):RecyclerViewCardView了解一下界面无小事(二):让RecyclerView展示更多不同视图界面无小事(三):用RecyclerView Toolbar做个文件选择器界面无小事(四):来写个滚动选择器吧!界面无小事(五):自定义TextView界面无小事(六):来做个好看得侧拉菜单!界面无小事(七):使…