2_scrapy数据建模及请求参数

1. 数据建模

1.1 为何要建模

  • item中提前定义好需要抓取的内容,防止在爬虫文件中误写
  • 提前定义加注释和明确目标

1.2 如何建模

item.py

class MyspiderItem(scrapy.Item): 
    name = scrapy.Field()   # 讲师的名字
    title = scrapy.Field()  # 讲师的职称
    desc = scrapy.Field()   # 讲师的介绍

1.3 如何使用建好的模

在爬虫文件中在

from myspider.items import MyspiderItem   # 1. 导入Item,注意路径
...
    def parse(self, response)

        item = MyspiderItem() # 2. 实例化后可直接使用

        item['name'] = node.xpath('./h3/text()').extract_first()
        item['title'] = node.xpath('./h4/text()').extract_first()
        item['desc'] = node.xpath('./p/text()').extract_first()
        
        print(item)
        yield item # 3. 传递给pipeline

1.4 开发基本流程总结

  1. 开启项目:scrapy startproject CSDN
  2. 创建爬虫模板:先cd CSDN,然后scrapy genspider csdn csdn.net
  3. 明确爬虫目标,修改item.py文件
  4. 完善爬虫文件:csdn.py
    1. start_url
    2. 完善parse方法
  5. 保存数据:修改pipelines.py和开启setting.py中参数

2. Request请求的应用–翻页、同时爬取其他页面

2.1 如何实现翻页

  • 找到下一页url
  • 构造翻页请求对象,传递给引擎

2.2 实现方法

  • 确定下一页url
  • 构造请求对象:scrapy.Request(url, callback=self.parse)
  • 提交给引擎:yield scrapy.Request(url, callback=self.parse)

2.3 示例

爬取暨南大学学院教师基本信息

import scrapy
from jnuteachers.items import JnuteachersItem

class JnuSpider(scrapy.Spider):
    name = 'jnu'
    allowed_domains = ['jnu.edu.cn']
    start_urls = ['http://xxxy2016.jnu.edu.cn/Category_96/Index.aspx']
    flag = 0

    def parse(self, response):
        ls = response.xpath('//*[@id="techerList"]/div[2]/ul/li')

        for tmp in ls:
            item = JnuteachersItem()
            item['name'] = tmp.xpath('./span[1]/a/text()').extract_first()
            item['link'] = response.urljoin(tmp.xpath('./span[1]/a/@href').extract_first())
            item['level'] = tmp.xpath('./span[2]/text()').extract_first()
            item['direction'] = tmp.xpath('./span[3]/text()').extract_first()
            item['email'] = tmp.xpath('./span[4]/text()').extract_first()
        
        part_url = response.xpath('//*[@id="pe100_page_通用信息列表_领导式"]/div/a[4]/@href').extract_first()
        print('part_url:',part_url)
        last_url = response.xpath('//*[@id="pe100_page_通用信息列表_领导式"]/div/a[5]/@href').extract_first()
        print('last_url:',last_url)
        print(JnuSpider.flag)

        if (part_url != last_url) or (JnuSpider.flag == 0):
            if part_url == last_url:
                JnuSpider.flag += 1
            next_url = 'http://xxxy2016.jnu.edu.cn/Category_96/' + part_url
            yield scrapy.Request(
                url = next_url,
                callback= self.parse
            )

2.4 Request参数详解

scrapy.Request(url[,callback,method="GET",headers,body,cookies,meta,dont_filter=False])
参数解释

  1. 中括号里的参数为可选参数
  2. callback:表示当前的url的响应交给哪个函数去处理
  3. meta:实现数据在不同的解析函数中传递,meta默认带有部分数据,比如下载延迟,请求深度等
  4. dont_filter:默认为False,会过滤请求的url地址,即请求过的url地址不会继续被请求,对需要重复请求的url地址可以把它设置为Ture,比如贴吧的翻页请求,页面的数据总是在变化;start_urls中的地址会被反复请求,否则程序不会启动
  5. method:指定POST或GET请求
  6. headers:接收一个字典,其中不包括cookies
  7. cookies:接收一个字典,专门放置cookies
  8. body:接收json字符串,为POST的数据,发送payload_post请求时使用

2.5 Request中meta参数的使用

可以用于解析当前页面中链接的其他页面数据

注意:meta参数是一个字典meta={“item”:item}

def parse(self,response):
    ...
    yield scrapy.Request(detail_url, callback=self.parse_detail,meta={"item":item})
...

def parse_detail(self,response):
    #获取之前传入的item
    item = resposne.meta["item"]
import scrapy
from jnuteachers.items import JnuteachersItem

class JnuSpider(scrapy.Spider):
    name = 'jnu'
    allowed_domains = ['jnu.edu.cn']
    start_urls = ['http://xxxy2016.jnu.edu.cn/Category_96/Index.aspx']
    flag = 0

    def parse(self, response):
        ls = response.xpath('//*[@id="techerList"]/div[2]/ul/li')
        print(len(ls))
        for tmp in ls:
            # 使用建立的模板对象
            item = JnuteachersItem()
            item['name'] = tmp.xpath('./span[1]/a/text()').extract_first()
            item['link'] = response.urljoin(tmp.xpath('./span[1]/a/@href').extract_first())
            item['level'] = tmp.xpath('./span[2]/text()').extract_first()
            item['direction'] = tmp.xpath('./span[3]/text()').extract_first()
            item['email'] = tmp.xpath('./span[4]/text()').extract_first()
            print(item)
            # 对链接其他页的请求构造及传递给引擎
            yield scrapy.Request(url=item['link'], callback=self.detail_url,meta={'item':item})
        
        # 获取下一页和尾页的地址
        part_url = response.xpath('//*[@id="pe100_page_通用信息列表_领导式"]/div/a[4]/@href').extract_first()
        last_url = response.xpath('//*[@id="pe100_page_通用信息列表_领导式"]/div/a[5]/@href').extract_first()

        # 对翻页的处理以及尾页的处理
        if (part_url != last_url) or (JnuSpider.flag == 0):
            if part_url == last_url:
                JnuSpider.flag += 1
            next_url = 'http://xxxy2016.jnu.edu.cn/Category_96/' + part_url
            # 对下一页的请求构造对象及传递给引擎
            yield scrapy.Request(
                url = next_url,
                callback= self.parse
            )
    
    # 处理链接的其他页面抓取
    def detail_url(self,response):
        item = response.meta['item']
        item['exp'] = response.xpath('//*[@id="Education"]/div[2]/p/span/text()').extract()
        item['result'] = response.xpath('//*[@id="Winning"]/div[2]/p/span/text()').extract()
        print(item)
        yield item
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值