爬虫-第五篇-scrapy框架初识,持久化存储,手动请求发送

news/2024/7/4 10:05:12

准备工作

  • 什么是框架?如何学习框架?

    就是一个集成了各种功能且具有很强通用性(可以被应用在各种不同的需求中)的一个项目模板.

  • scrapy集成了哪些功能:

    • 高性能的数据解析操作,持久化存储操作,高性能的数据下载的操作.....
  • 环境的安装:

    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
    
    d. pip3 install pywin32
    
    e. pip3 install scrapy

scrapy的基本使用

  • 创建一个工程:scrapy startproject firstBlood
  • 必须在spiders这个目录下创建一个爬虫文件
    • cd 项目目录
    • scrapy genspider spiderName www.xxx.com
  • 执行工程:scrapy crawl spiderName
import scrapy


class FirstSpider(scrapy.Spider):
    #爬虫文件的名称:爬虫文件的唯一标识(在spiders子目录下是可以创建多个爬虫文件)
    name = 'first'
    #允许的域名
    # allowed_domains = ['www.baidu.com']
    #起始的url列表:列表中存放的url会被scrapy自动的进行请求发送
    start_urls = ['https://www.baidu.com/','https://www.sogou.com/']
    #用作于数据解析:将start_urls列表中对应的url请求成功后的响应数据进行解析
    def parse(self, response):
        print(response)
  • settings.py:

    • 不遵从robots协议
    • 进行UA伪装
    • 进行日志等级设定:LOG_LEVEL = 'ERROR'

    持久化存储

    基于终端指令:

    • 特性:只可以将parse方法的返回值存储到本地的磁盘文件中
    • 指令:scrapy crawl spiderName -o filePath
    • 文件名后缀只能是json,csv,xml,pickle等
def parse(self, response):
    div_list = response.xpath('//*[@id="content-left"]/div')
    all_data = []
    for div in div_list:
        author = div.xpath('./div[1]/a[2]/h2/text()').extract_first()  
        content = div.xpath('./a[1]/div/span//text()').extract()
        content = ''.join(content)
        #构建数据结构
        dic = {
            'author':author,
            'content':content
        }
        all_data.append(dic)
        return all_data

基于管道

  • 实现流程
    1.数据解析
    2.在item类中定义相关的属性

    # item.py
    import scrapy
    class QiubaiproItem(scrapy.Item):
        # define the fields for your item here like:
        author = scrapy.Field() #Field可以将其理解成是一个万能的数据类型
        content = scrapy.Field()

    3.将解析的数据存储或者封装到一个item类型的对象(items文件中对应类的对象)

    # qiubai.py
    def parse(self, response):
        div_list = response.xpath('//*[@id="content-left"]/div')
        all_data = []
        for div in div_list:
            author = div.xpath('./div[1]/a[2]/h2/text()').extract_first()
            content = div.xpath('./a[1]/div/span//text()').extract()
            content = ''.join(content)
    
            #将解析的数据存储到item对象
            item = QiubaiproItem()
            item['author'] = author
            item['content'] = content
    
            #将item提交给管道
            yield item #item一定是提交给了优先级最高的管道类

    4.向管道提交item--->yield
    5.在管道文件的process_item方法中接收item进行持久化存储

    class QiubaiproPipeline(object):
        fp = None
        def open_spider(self,spider):
            print('开始爬虫......')
            self.fp = open('qiushibaike.txt','w',encoding='utf-8')
    
        #使用来接收爬虫文件提交过来的item,然后将其进行任意形式的持久化存储
        #参数item:就是接收到的item对象
        #该方法每接收一个item就会调用一次
        def process_item(self, item, spider):
            author = item['author']
            content= item['content']
    
            self.fp.write(author+':'+content+'\n')
            return item #item是返回给了下一个即将被执行的管道类
    
        def close_spider(self,spider):
            print('结束爬虫!')
            self.fp.close()

    6.在配置文件中开启管道

    # settings.py
    ITEM_PIPELINES = {
       'qiubaiPro.pipelines.QiubaiproPipeline': 300, #300表示的是优先级
       #  'qiubaiPro.pipelines.MysqlPL': 301,
       #  'qiubaiPro.pipelines.RedisPL': 302,
    }

将同一份数据持久化到不同的平台

  • 1.管道文件中的一个管道类负责数据的一种形式的持久化存储
  • 2.爬虫文件向管道提交的item只会提交给优先级最高的那一个管道类
  • 3.在管道类的process_item中的return item表示的是将当前管道接收的item返回/提交给
    下一个即将被执行的管道类
#负责将数据存储到mysql
class MysqlPL(object):
    conn = None
    cursor = None
    def open_spider(self,spider):
        self.conn = pymysql.Connect(host='127.0.0.1',port=3306,user='root',password='123',db='spider',charset='utf8')
        print(self.conn)
    def process_item(self,item,spider):
        author = item['author']
        content = item['content']

        sql = 'insert into qiubai values ("%s","%s")'%(author,content)
        self.cursor = self.conn.cursor()
        try:
            self.cursor.execute(sql)
            self.conn.commit()
        except Exception as e:
            print(e)
            self.conn.rollback()
        return item
    def close_spider(self,spider):
        self.cursor.close()
        self.conn.close()

class RedisPL(object):
    conn = None
    def open_spider(self,spider):
        self.conn = Redis(host='127.0.0.1',port=6379)
        print(self.conn)
    def process_item(self,item,spider):
        self.conn.lpush('all_data',item)
        #注意:如果将字典写入redis报错:pip install -U redis==2.10.6

在scrapy中如何进行手动请求发送

手动请求发送(GET)

  • 使用场景:爬取多个页码对应的页面源码数据
  • yield scrapy.Request(url,callback)
 #将多个页码对应的页面数据进行爬取和解析的操作
    url = 'https://www.qiushibaike.com/text/page/%d/'#通用的url模板
    pageNum = 1
    #parse第一次调用表示的是用来解析第一页对应页面中的段子内容和作者
    def parse(self, response):
        div_list = response.xpath('//*[@id="content-left"]/div')
        all_data = []
        for div in div_list:
            # scrapy中的xpath返回的列表的列表元素一定是Selector对象,我们最终想要的解析的
            # 数据一定是存储在该对象中
            # extract()将Selector对象中data参数的值取出
            # author = div.xpath('./div[1]/a[2]/h2/text()')[0].extract()
            author = div.xpath('./div[1]/a[2]/h2/text()').extract_first()

            # 列表直接调用extract表示的是将extract作用到每一个列表元素中
            content = div.xpath('./a[1]/div/span//text()').extract()

            content = ''.join(content)

            # 将解析的数据存储到item对象
            item = QiubaiproItem()
            item['author'] = author
            item['content'] = content

            # 将item提交给管道
            yield item  # item一定是提交给了优先级最高的管道类

        if self.pageNum <= 5:
            self.pageNum += 1
            new_url = format(self.url%self.pageNum)
            #手动请求(get)的发送
            yield scrapy.Request(new_url,callback=self.parse)

手动请求发送(POST)

data = { #post请求的请求参数
'kw':'aaa'
}
yield scrapy.FormRequest(url,formdata=data,callback)

很少用此框架发送post请求

scrapy五大核心组件的工作流程

引擎(Scrapy)

​ 用来处理整个系统的数据流处理, 触发事务(框架核心)
调度器(Scheduler)
​ 用来接受引擎发过来的请求, 压入队列中, 并在引擎再次请求的时候返回. 可以想像成一个URL(抓取网页的网址或者说是链接)的优先队列, 由它来决定下一个要抓取的网址是什么, 同时去除重复的网址
下载器(Downloader)
​ 用于下载网页内容, 并将网页内容返回给蜘蛛(Scrapy下载器是建立在twisted这个高效的异步模型上的)
爬虫(Spiders)
​ 爬虫是主要干活的, 用于从特定的网页中提取自己需要的信息, 即所谓的实体(Item)。用户也可以从中提取出链接,让Scrapy继续抓取下一个页面
项目管道(Pipeline)
​ 负责处理爬虫从网页中抽取的实体,主要的功能是持久化实体、验证实体的有效性、清除不需要的信息。当页面被爬虫解析后,将被发送到项目管道,并经过几个特定的次序处理数据。

转载于:https://www.cnblogs.com/yinhaiping/p/11437345.html


http://www.niftyadmin.cn/n/3458659.html

相关文章

出来混迟早要还的,技术债Dagger2:Android篇(上)

前言 因为工作需求&#xff0c;所以最近补了补之前没了解过的Dagger2的内容&#xff0c;基础篇已经发布。接下来就是Dagger2在Android中的应用了。当然&#xff0c;和我一样刚接触Dagger2的朋友&#xff0c;可以先看一下之前的基础文章&#xff1a; 出来混迟早要还的&#xff0…

JVM学习笔记之认识JDK(一)

1. HotSpot VM&#xff1a; HotSpot VM是Sun JDK和OpenJDK中所带的虚拟机&#xff0c;也是目前使用范围最广的Java虚拟机。 什么是HotSpot VM & 深入理解Java虚拟机 JVM? 提起HotSpot VM&#xff0c;相信所有Java程序员都知道&#xff0c;它是Sun JDK和OpenJDK中所带的虚拟…

JVM学习笔记之JDK、JRE、JVM的关系(二)

JDK&#xff08;Java Development Kit&#xff09;是针对Java开发员的产品&#xff0c;是整个Java的核心&#xff0c;包括了Java运行环境JRE、Java工具和Java基础类库。Java Runtime Environment&#xff08;JRE&#xff09;是运行JAVA程序所必须的环境的集合&#xff0c;包含J…

开发函数计算的正确姿势——运行 Selenium Java

2019独角兽企业重金招聘Python工程师标准>>> 前言 首先介绍下在本文出现的几个比较重要的概念&#xff1a; 函数计算&#xff08;Function Compute&#xff09;: 函数计算是一个事件驱动的服务&#xff0c;通过函数计算&#xff0c;用户无需管理服务器等运行情况&am…

JVM学习笔记之初识JVM(三)

一、JVM在计算机中的位置 JVM调用操作系统&#xff0c;操作系统调用硬件&#xff0c;硬件反馈信息至操作系统&#xff0c;操作系统反馈信息至JVM 二、JVM的体系结构 JVM在执行过程中对内存的管理分为5个区域&#xff1a; 1.PC寄存器 2.Java虚拟机栈(JVM Stack) 3.本地方法栈(Na…

【转】协同开发中SVN使用规范试用

转自&#xff1a;http://www.cnblogs.com/BraveCheng/archive/2012/07/02/2573617.html 协同开发中SVN使用规范试用 目标&#xff0c;要求 本次svn提交规范主要针对当前项目中出现的svn管理难&#xff0c;开发流程控制难掌控&#xff0c;项目进度记录不准确等问题而提出。要求每…

学无止境·MySQL(3-2)

单表查询试题 单表题目一1、创建表2、查询出部门编号为30的所有员工3、所有销售员的姓名、编号和部门编号4、找出奖金高于工资的员工5、找出奖金高于工资60%的员工。6、 找出部门编号为10中所有经理&#xff0c;和部门编号为20中所有销售员的详细资料。7、找出部门编号为10中所…

爬虫-第六篇-scrapy图片爬取,请求传参,中间件,提升爬取效率

补充: 自动请求start_urls列表路径其实是执行了父类中的start_requests方法,默认为GET请求,如果想要发送POST请求,改写此方法即可. def start_requests(self):for url in self.start_urls:yield scrapy.Request(url,callbackself.parse) # LOG_FILE ./log.txt 日志文件输出,默…