Scrapy框架(八)--CrawlSpider

CrawlSpider类,Spider的一个子类
  - 全站数据爬取的方式
    - 基于Spider:手动请求
    - 基于CrawlSpider
  - CrawlSpider的使用:
    - 创建一个工程
    - cd XXX
  - 创建爬虫文件(CrawlSpider):
    - scrapy genspider -t crawl xxx www.xxxx.com
    - 链接提取器:
      - 作用:根据指定的规则(allow)进行指定链接的提取
    - 规则解析器:
      - 作用:将链接提取器提取到的链接进行指定规则(callback)的解析

 

示例:爬取sun网站中的编号,新闻标题,新闻内容,标号

分析:爬取的数据没有在同一张页面中。
  - 1.可以使用链接提取器提取所有的页码链接
  - 2.让链接提取器提取所有的新闻详情页的链接

爬虫文件

# -*- coding: utf-8 -*-
import scrapy
from scrapy.linkextractors import LinkExtractor
from scrapy.spiders import CrawlSpider, Rule
from Sun.items import SunItem,DetailItem


class SunSpider(CrawlSpider):
    name = 'sun'
    # allowed_domains = ['www.xxx.com']
    start_urls = ['http://wz.sun0769.com/political/index/politicsNewest?id=1&type=4']
    # 链接提取器:根据指定规则进行指定链接的提取
    link = LinkExtractor(allow=r'id=1&page=\d+')
    link_detail = LinkExtractor(allow=r'index\?id=\d+')  # 一个链接提取器对应一个规则解析器
    rules = (
        # 规则解析器:将链接提取器提取到的链接发送请求 并根据callback进行指定的解析操作
        Rule(link, callback='parse_item', follow=False),
        # follow=True 可以将链接提取器继续作用到 链接提取器提取的链接所对应的页面
        # 通过此设置可对所有的页码进行爬取 调度器有去重过滤功能
        Rule(link_detail, callback='parse_detail', follow=False),
    )

    # 以下两个方法不可以进行请求传参
    # 两个方法都把数据存储到item中 可采用两个item
    def parse_item(self, response):
        li_list = response.xpath('/html/body/div[2]/div[3]/ul[2]/li')
        for li in li_list:
            new_num = li.xpath('./span[1]/text()').extract_first()
            title = li.xpath('./span[3]/a/text()').extract_first()
            item = SunItem()
            item['new_num'] = new_num
            item['title'] = title
            yield item

    def parse_detail(self, response):
        print(111)
        item = DetailItem()
        new_id = response.xpath('/html/body/div[3]/div[2]/div[2]/div[1]/span[4]/text()').extract_first()
        content = response.xpath('/html/body/div[3]/div[2]/div[2]/div[2]//text()').extract_first()
        print(new_id, content)
        item['new_id'] = new_id
        item['content'] = content
        yield item

items.py

class SunPipeline:

    def process_item(self, item, spider):

        if item.__class__.__name__ == 'SunItem':  # 获取当前的item的类名的字符串
            new_num = item['new_num']
            title = item['title']
        else:
            print(22)
            new_id = item['new_id']
            content = item['content']
            print(new_id,content)
        return item

注:在写正则表达式时,需要对特殊的符号进行转义。

posted @ 2020-06-30 21:27  Mrterrific  阅读(237)  评论(0编辑  收藏  举报