scrapy框架初识(Spider模块,CrawlSpider模块的使用)

一.什么是Scrapy?

  Scrapy是一个为了爬取网站数据,提取结构性数据而编写的应用框架,非常出名,非常强悍。所谓的框架就是一个已经被集成了各种功能(高性能异步下载,队列,分布式,解析,持久化等)的具有很强通用性的项目模板。对于框架的学习,重点是要学习其框架的特性、各个功能的用法即可。

二.安装

复制代码
Linux:
      pip3 install scrapy

  Windows:
      a. pip3 install wheel
      b. 下载twisted http://www.lfd.uci.edu/~gohlke/pythonlibs/#twisted
      c. 进入下载目录,执行 pip3 install Twisted‑17.1.0‑cp35‑cp35m‑win_amd64.whl  # 要与b的版本保持一致
      d. pip3 install pywin32
      e. pip3 install scrapy
复制代码

三.基础使用

  1.创建项目:scrapy startproject 项目名称   

复制代码
项目结构:

project_name/
   scrapy.cfg:
   project_name/
       __init__.py
       items.py
       pipelines.py
       settings.py
       spiders/
           __init__.py

scrapy.cfg   项目的主配置信息。(真正爬虫相关的配置信息在settings.py文件中)
items.py     设置数据存储模板,用于结构化数据,如:Django的Model
pipelines    数据持久化处理
settings.py  配置文件,如:递归的层数、并发数,延迟下载等
spiders      爬虫目录,如:创建文件,编写爬虫解析规则
复制代码

 2.创建爬虫应用程序:

      cd project_name(进入项目目录)

      scrapy genspider 应用名称 爬取网页的起始url (例如:scrapy genspider qiubai www.qiushibaike.com)

 3.编写爬虫文件:在步骤2执行完毕后,会在项目的spiders中生成一个应用名的py爬虫文件,文件源码如下:

复制代码
# -*- coding: utf-8 -*-
import scrapy

class QiubaiSpider(scrapy.Spider):
    name = 'qiubai' #应用名称
    #允许爬取的域名(如果遇到非该域名的url则爬取不到数据)
    allowed_domains = ['https://www.qiushibaike.com/']
    #起始爬取的url
    start_urls = ['https://www.qiushibaike.com/']

     #访问起始URL并获取结果后的回调函数,该函数的response参数就是向起始的url发送请求后,获取的响应对象.该函数返回值必须为可迭代对象或者NUll 
     def parse(self, response):
        print(response.text) #获取字符串类型的响应内容
        print(response.body)#获取字节类型的相应内容
复制代码

  4.设置修改settings.py配置文件相关配置:

修改内容及其结果如下:
19行:USER_AGENT = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36' #伪装请求载体身份

22行:ROBOTSTXT_OBEY = False  #可以忽略或者不遵守robots协议

      5.执行爬虫程序:scrapy crawl  应用名称

四.小试牛刀:将糗百首页中段子的内容和标题进行爬取

复制代码
import scrapy
from day04.items import Day04Item

class QiubaiSpider(scrapy.Spider):
    name = 'qiubai'
    #allowed_domains = ['https://www.qiushibaike.com/']
    start_urls = ['https://www.qiushibaike.com/text/']

基于管道的持久化储存
    def parse(self, response):
        # xpath为response中的方法,可以将xpath函数直接作用于该函数中
        odiv = response.xpath('//div[@id="content-left"]/div')
        content_list = []  # 用于储存解析到的数据
        for div in odiv:
            # xpath函数返回的为列表,列表中存放的数据为Selector类型的数据。
            # 我们解析到的内容被封装在了Selector对象中,
            # 需要调用extract()函数将解析的内容从Selecor中取出。

            # author = div.xpath('./div[@class="author clearfix"]/a[2]/h2/text()')[0].extract()
            # content = div.xpath('./a/div[@class="content"]/span[1]/text()')[0].extract()

            author = div.xpath('./div/a[2]/h2/text()').extract_first()  # 不用执行[0]操作
            content = div.xpath('./a/div[@class="content"]/span//text()').extract()
            content = "".join(content)

            # 将解析到的内容封装到字典中
            dic = {
                '作者': author,
                '内容': content
            }
            # 将数据储存到content_list这个列表中
            content_list.append(dic)

        return content_list
     终端执行爬虫程序:
         # D:\package\jupyter\day04>scrapy crawl qiubai -o text.csv
         # 测试通不通时,执行:scrapy crawl qiubai --nolog
          #测试查看错误信息时,执行:scrapy crawl qiubai
复制代码

执行爬虫程序:

 scrapy crawl 爬虫名称 :该种执行形式会显示执行的日志信息
 scrapy crawl 爬虫名称 --nolog:该种执行形式不会显示执行的日志信息

 高级使用

提问:如果想要通过爬虫程序去爬取”糗百“全站数据新闻数据的话,有几种实现方法?

方法一:基于Scrapy框架中的Spider的递归爬取进行实现(Request模块递归回调parse方法)。

方法二:基于CrawlSpider的自动爬取进行实现(更加简洁和高效)。

一.简介

  CrawlSpider其实是Spider的一个子类,除了继承到Spider的特性和功能外,还派生除了其自己独有的更加强大的特性和功能。其中最显著的功能就是”LinkExtractors链接提取器“。Spider是所有爬虫的基类,其设计原则只是为了爬取start_url列表中网页,而从爬取到的网页中提取出的url进行继续的爬取工作使用CrawlSpider更合适。

二.使用

  1.创建scrapy工程:scrapy startproject projectName

  2.创建爬虫文件:scrapy genspider -t crawl spiderName www.xxx.com

    --此指令对比以前的指令多了 "-t crawl",表示创建的爬虫文件是基于CrawlSpider这个类的,而不再是Spider这个基类。

  3.观察生成的爬虫文件

复制代码
# -*- coding: utf-8 -*-
import scrapy
from scrapy.linkextractors import LinkExtractor
from scrapy.spiders import CrawlSpider, Rule


class ChoutidemoSpider(CrawlSpider):
    name = 'choutiDemo'
    #allowed_domains = ['www.chouti.com']
    start_urls = ['http://www.chouti.com/']

    rules = (
        Rule(LinkExtractor(allow=r'Items/'), callback='parse_item', follow=True),
    )

    def parse_item(self, response):
        i = {}
        #i['domain_id'] = response.xpath('//input[@id="sid"]/@value').extract()
        #i['name'] = response.xpath('//div[@id="name"]').extract()
        #i['description'] = response.xpath('//div[@id="description"]').extract()
        return i
复制代码

  - 2,3行:导入CrawlSpider相关模块

  - 7行:表示该爬虫程序是基于CrawlSpider类的

  - 12,13,14行:表示为提取Link规则

  - 16行:解析方法

  CrawlSpider类和Spider类的最大不同是CrawlSpider多了一个rules属性,其作用是定义”提取动作“。在rules中可以包含一个或多个Rule对象,在Rule对象中包含了LinkExtractor对象

3.1 LinkExtractor:顾名思义,链接提取器。 

复制代码
 LinkExtractor(

         allow=r'Items/'# 满足括号中“正则表达式”的值会被提取,如果为空,则全部匹配。

         deny=xxx,  # 满足正则表达式的则不会被提取。


         restrict_xpaths=xxx, # 满足xpath表达式的值会被提取

         restrict_css=xxx, # 满足css表达式的值会被提取

         deny_domains=xxx, # 不会被提取的链接的domains。 

    )
    - 作用:提取response中符合规则的链接。
复制代码

  3.2 Rule : 规则解析器。根据链接提取器中提取到的链接,根据指定规则提取解析器链接网页中的内容。 

复制代码
  Rule(LinkExtractor(allow=r'Items/'), callback='parse_item', follow=True)

    - 参数介绍:

      参数1:指定链接提取器

      参数2:指定规则解析器解析数据的规则(回调函数)

      参数3:是否将链接提取器继续作用到链接提取器提取出的链接网页中。当callback为None,参数3的默认值为true。
复制代码

  3.3 rules=( ):指定不同规则解析器。一个Rule对象表示一种提取规则。

  3.4 CrawlSpider整体爬取流程:

       a)爬虫文件首先根据起始url,获取该url的网页内容

    b)链接提取器会根据指定提取规则将步骤a中网页内容中的链接进行提取

    c)规则解析器会根据指定解析规则将链接提取器中提取到的链接中的网页内容根据指定的规则进行解析

    d)将解析数据封装到item中,然后提交给管道进行持久化存储    

  4.简单代码实战应用

      4.1 爬取糗事百科糗图板块的所有页码数据

复制代码
# -*- coding: utf-8 -*-
import scrapy
from scrapy.linkextractors import LinkExtractor
from scrapy.spiders import CrawlSpider, Rule


class CrawldemoSpider(CrawlSpider):
    name = 'qiubai'
    #allowed_domains = ['www.qiushibaike.com']
    start_urls = ['https://www.qiushibaike.com/pic/']

    #连接提取器:会去起始url响应回来的页面中提取指定的url
    link = LinkExtractor(allow=r'/pic/page/\d+\?') #s=为随机数
    link1 = LinkExtractor(allow=r'/pic/$')#爬取第一页
    #rules元组中存放的是不同的规则解析器(封装好了某种解析规则)
    rules = (
        #规则解析器:可以将连接提取器提取到的所有连接表示的页面进行指定规则(回调函数)的解析
        Rule(link, callback='parse_item', follow=True),
        Rule(link1, callback='parse_item', follow=True),
    )

    def parse_item(self, response):
        print(response)
复制代码

 4.2 爬虫文件:

复制代码
# -*- coding: utf-8 -*-
import scrapy
from scrapy.linkextractors import LinkExtractor
from scrapy.spiders import CrawlSpider, Rule
from qiubaiBycrawl.items import QiubaibycrawlItem
import re
class QiubaitestSpider(CrawlSpider):
    name = 'qiubaiTest'
    #起始url
    start_urls = ['http://www.qiushibaike.com/']

    #定义链接提取器,且指定其提取规则
    page_link = LinkExtractor(allow=r'/8hr/page/\d+/')
    
    rules = (
        #定义规则解析器,且指定解析规则通过callback回调函数
        Rule(page_link, callback='parse_item', follow=True),
    )

    #自定义规则解析器的解析规则函数
    def parse_item(self, response):
        div_list = response.xpath('//div[@id="content-left"]/div')
        
        for div in div_list:
            #定义item
            item = QiubaibycrawlItem()
            #根据xpath表达式提取糗百中段子的作者
            item['author'] = div.xpath('./div/a[2]/h2/text()').extract_first().strip('\n')
            #根据xpath表达式提取糗百中段子的内容
            item['content'] = div.xpath('.//div[@class="content"]/span/text()').extract_first().strip('\n')

            yield item #将item提交至管道
复制代码

  4.2 item文件:

复制代码
# -*- coding: utf-8 -*-

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

import scrapy


class QiubaibycrawlItem(scrapy.Item):
    # define the fields for your item here like:
    # name = scrapy.Field()
    author = scrapy.Field() #作者
    content = scrapy.Field() #内容
复制代码

  4.3 管道文件:

复制代码
# -*- coding: utf-8 -*-

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

class QiubaibycrawlPipeline(object):
    
    def __init__(self):
        self.fp = None
        
    def open_spider(self,spider):
        print('开始爬虫')
        self.fp = open('./data.txt','w')
        
    def process_item(self, item, spider):
        #将爬虫文件提交的item写入文件进行持久化存储
        self.fp.write(item['author']+':'+item['content']+'\n')
        return item
    
    def close_spider(self,spider):
        print('结束爬虫')
        self.fp.close()
复制代码

123
posted @   老虎死了还有狼  阅读(1205)  评论(0编辑  收藏  举报
编辑推荐:
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
阅读排行:
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
点击右上角即可分享
微信分享提示