方法教程 | 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文件

# -*- 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爬虫文件


# -*- 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 

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


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管道文件 


# -*- 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全剧配置文件

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文件


from scrapy import cmdline

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

这是保存下来的Python爬虫:使用scrapy框架爬取腾某的岗位,如有不足之处或更多技巧,欢迎指教补充。愿本文的分享对您之后爬虫有所帮助。谢谢~

编辑排版:筱筱   原创:杨旭华啊

图片

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值