scrapy异步加载多级爬虫_智联招聘

  吼吼吼!终于写到这里了,今天写用scrapy框架写多级爬虫,目标网站是智联招聘,要爬取的数据是上海地区学位要求是本科及以上的所有岗位数据。

  主要过程描述,首先爬取到每个职位的详细url,再进入职位的url中获取更详细的信息。在一级页面上我们可以获取这些信息:
一级页面在二级页面上获取这些信息:
在二级页面上获取信息  大致的流程是这样,接下来开始分析网页。

  目标地址页面在这儿,要注意,这里是个ajax异步加载网页:
异步加载 发现传输过来的数据都是json格式。
  这里插句题外话,怎么发现是异步加载呢,我们在scrapy shell 里爬取目标网页:

scrapy shell https://sou.zhaopin.com/?jl=538&sf=0&st=0&el=4

打印response.text,发现跟我们在浏览器审查元素里看到的不一样:
response.text 打印结果然后在审查元素里查看网络,选择持续日志,选择xhr文件类型:
选择xhr发现随着页面更新或翻页xhr在不断增加,就说明这是一个异步加载网页了。
发现有不断增加的xhr  好了,回到正题,怎么爬取异步加载返回的内容呢。
首先一个个点开看响应内容:
第一个xhr的响应内容发现传回的是三个c_pc_chat_job,,没有我们需要的职位信息。
再看下一个xhr的响应内容:
第二个xhr的返回内容发现传回的像网站首页的相关说明和标题,还是没有我们需要的信息。
一个页面刷新触发了三个xhr,两个都没有我们想要的,就剩最后一个了。
第三个xhr返回的信息  嗯?好像有点内容,我们来仔细看看这个results,发现这里面就是我们需要的信息。
在这里插入图片描述  这只是第一个数据,拉到下面会发现总共有90条数据,也就是每个一级页面显示90个职位,接下来就简单了。
  我们看到消息头:
在这里插入图片描述  这里的请求网址,就是我们以及一级页面真正的请求网址!所以不要在crawl https://sou.zhaopin.com/?jl=538&sf=0&st=0&el=4 这个浏览器上看到的网址啦,而应该看这里的地址。主host是https://fe-api.zhaopin.com/c/i/sou 后面跟着的都是参数!(这里需要懂一点前端的知识哦
  找到了正确的请求地址后,我们接下来分析它的翻页参数变化规律,点击“参数”:
第一页的参数列表  同样的方法,找到第二页正确的xhr,并查看其参数,发现从第二页开始,多了一个start参数,并每翻一页就增加90,同时其余参数保持不变。
  这样我们就找到了正确的一级页面变化规律:
第一个网址为:https://fe-api.zhaopin.com/c/i/sou?pageSize=90&cityId=538&salary=0,0&workExperience=-1&education=4&companyType=-1&employmentType=-1&jobWelfareTag=-1&kt=3&=0&_v=0.37561803&x-zp-page-request-id=a666d29fef2a4f6687cf5a7e1582ae4e-1562416715999-715744&x-zp-client-id=ef45bbd9-7323-4413-8367-8781cc2579bc
  第二个页面为:https://fe-api.zhaopin.com/c/i/sou?start=90&pageSize=90&cityId=538&salary=0,0&workExperience=-1&education=4&companyType=-1&employmentType=-1&jobWelfareTag=-1&kt=3&=0&_v=0.37561803&x-zp-page-request-id=a666d29fef2a4f6687cf5a7e1582ae4e-1562416715999-715744&x-zp-client-id=ef45bbd9-7323-4413-8367-8781cc2579bc
  此后每个页面的start以90为步进递增,其他参数不变。
  到这里,就该讲下怎么解析json里的文件,我们需要倒入一个json包,用json.loads方法,将json解析为字典格式,再通过字典的多层索引方法获取里面相应的值:

# -*- coding: utf-8 -*-
import scrapy
from zhilian.items import ZhilianItem
import json


class JobsSpiderSpider(scrapy.Spider):
    name = 'jobs_spider'
    start_urls = ['https://fe-api.zhaopin.com/c/i/sou?pageSize=90&cityId=538&salary=0,0&workExperience=-1&education=4&companyType=-1&employmentType=-1&jobWelfareTag=-1&kt=3&=0&_v=0.34726331&x-zp-page-request-id=288eb86dfb8d4d9692a7f0d6b2feb1eb-1561768556928-40960&x-zp-client-id=ef45bbd9-7323-4413-8367-8781cc2579bc']
    for i in range(90, 991, 90):
        page_start = 'start={}&'.format(i)
        urls = 'https://fe-api.zhaopin.com/c/i/sou?{}pageSize=90&cityId=538&salary=0,0&workExperience=-1&education=4&companyType=-1&employmentType=-1&jobWelfareTag=-1&kt=3&=0&_v=0.34726331&x-zp-page-request-id=288eb86dfb8d4d9692a7f0d6b2feb1eb-1561768556928-40960&x-zp-client-id=ef45bbd9-7323-4413-8367-8781cc2579bc'.format(page_start)
        start_urls.append(urls)
        
def start_requests(self):
        for url in self.start_urls:
            yield scrapy.Request(url, callback=self.parse_urls)

    def parse_urls(self, response):
        job_list = json.loads(response.text)['data']['results']
        for j in range(0, len(job_list)):
            items = ZhilianItem()
            items['date'] = job_list[j]['updateDate']
            items['job_name'] = job_list[j]['jobName']
            items['job_url'] = job_list[j]['positionURL']
            items['company_id'] = job_list[j]['company']['number']
            items['city'] = job_list[j]['city']['display']
            items['company'] = job_list[j]['company']['name']
            items['company_type'] = job_list[j]['company']['type']['name']
            items['salary'] = job_list[j]['salary']
            items['experience'] = job_list[j]['workingExp']['name']
            items['education'] = job_list[j]['eduLevel']['name']
            items['address'] = job_list[j]['businessArea']
            job_detail_url = job_list[j]['positionURL']
            yield scrapy.Request(job_detail_url, meta={'items': items}, callback=self.parse_job_detail_url, dont_filter=True)

  到这里就是爬取到一级页面的相关信息,接下来我们要进入二级页面中去爬取更详细的信息。
  观察我上面的代码。有个job_detail_url就是获取到的职位详情url,并调用scrapy.Request(url)方法进入到二级页面中。
  这里要注意一个参数,就是meta={'items': items},当项目需要在不同的页面中爬取时一定要传递这个参数,这样到后面的页面中用一句items = response.meta['items']沿用一个同items继续传递。
  到这里开始进入我们的二级页面。
  随意点入一个二级页面,发现不是异步加载,事情就好办多了,常规的爬取方法,xpath解析响应内容就可以了。

def parse_job_detail_url(self, response):
        items = response.meta['items']
        items['people_num'] = response.xpath('//ul[@class="summary-plane__info"]/li[4]/text()').extract()
        job_des = response.xpath('//div[@class="describtion__detail-content"]')
        items['job_description'] = job_des.xpath('string(.)').extract()
        yield items

  其他的相关设置不必多谈了,这里说几点亲身经历的踩雷点吧:

  • 有时候出现回调函数不执行或爬不到页面的情况,可能是有allowed_domin(我不记得是不是这个名字了)把一些链接过滤掉了,这个时候在scrapy.Request()里面加个参数dont_filter=True就可以了,可以参见我的代码。
  • 记得在setting.py文件里设置这几个东西:ROBOTSTXT_OBEY = False,请求头伪装和DOWNLOAD_DELAY = 1这里的下载延迟根据自己情况设定就好,不要访问太频繁了被限制访问。

  其他的没什么大问题了,有想交流的评论区见!
  附上爬到的部分数据截图:
数据截图

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值