• 4. scrapy框架基础


    scrapy框架基础

    1.安装

    Linux安装:
        pip install scrapy
    
    Windows安装:
        1.pip install wheel -- 可以安装 .whl文件
        2.下载twisted <http://www.lfd.uci.edu/~gohlke/pythonlibs/#twisted>
            - 找到对应自己电脑python版本
        3.进入下载目录,执行 pip install Twisted‑17.1.0‑cp35‑cp35m‑win_amd64.whl(下载的文件)
        4.pip install pywin32
        5.pip install scrapy  -- 安装scrapy爬虫框架
    

    2.基本操作

    1.创建一个工程:scrapy startproject 工程名
            - 工程目录中:
                - spiders:爬虫包
                - settings:工程的配置文件
    2.创建一个爬虫文件:
    	cd 工程名 -- 进入工程目录
    	scrapy genspider 爬虫文件名 www.xxx.com(随意网站,文件里能改)
        -数据的爬取和解析是需要编写在爬虫文件中
    3.执行工程:scrapy crawl 文件名
            - 程序会输出各种日志信息
                - 指定输入日志的类型:settings配置文件:LOG_LEVEL= 'ERROR'
            - robots.txt协议:君子协议,限制爬虫。
                - 如何忽略该协议:settings配置文件:ROBOTSTXT_OBEY = False
    

    简单使用

    import scrapy
    
    class FirstSpider(scrapy.Spider):
        #爬虫文件的名称:表示当前爬虫文件的唯一标识
        name = 'first'
        #允许的域名
        # allowed_domains = ['www.baidu.com']
        #起始url列表:列表中存放的url可以被scrapy进行get请求发送
        start_urls = ['https://www.baidu.com/','https://www.jd.com']
        #数据解析:response响应对象
        def parse(self, response):
            print(response)
    

    3.示例 -- 糗事百科 - 段子

    解析数据:

    settings配置上User-Agent
    多页解析时:
    - 手动请求发送:
    1.get请求:
        yield scrapy.Request(url=new_url,callback=self.parse)
    2.post请求:
        yield scrapy.FormRequest(url=new_url,callback=self.parse,formdata={})
    

    spiders/qiubai.py

    import scrapy
    
    class QiubaiSpider(scrapy.Spider):
        name = 'qiubai'
        # allowed_domains = ['www.xxx.com']
        start_urls = ['https://www.qiushibaike.com/text/']
    
        # 1. 数据解析:解析第一页
        # def parse(self, response):
        #     div_list = response.xpath('//*[@id="content"]/div/div[2]/div')
        #     for div in div_list:
        #         #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()返回的是列表
        #         content = div.xpath('./a[1]/div/span//text()').extract()
        #         content = ''.join(content)
        #         print(author,content)
    
        # 1.1 解析多页
        # 点击下一页通用的url模板
        url = 'https://www.qiushibaike.com/text/page/%d/'
        page_num = 2
        def parse(self, response):
    
            div_list = response.xpath('//*[@id="content"]/div/div[2]/div')
            for div in div_list:
                #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()返回的是列表
                content = div.xpath('./a[1]/div/span//text()').extract()
                content = ''.join(content)
                print(author,content)
            # 手动请求发送
            if self.page_num < 6: #
                new_url = format(self.url%self.page_num)
                self.page_num += 1
                yield scrapy.Request(url=new_url,callback=self.parse)
    

    持久化存储

    - 方案:
    	1.基于终端指令的持久化存储
            - 只可以将parase方法的返回值存储到指定后缀的文本文件中
            - 存储指令:scrapy crwal 爬虫文件名 -o 储存文件路径
    	2.基于管道的持久化存储(重点)
            - 在爬虫文件中进行数据解析
            - 在items文件中声明数据解析出的字段属性
            - 在爬虫文件中将解析出的字段存储封装到items类型的对象中
            - 将item对象提交给管道
            - 在管道文件的类中实现任意形式的持久化存储操作
    - 需要在配置文件中开启管道机制
        - 什么时候需要创建多个管道类?
        - 数据备份。一个管道类负责将数据存储到一种平台种。
    - 注意:爬虫文件提交过来的item只会给优先级最高的那一个管道类
        - 如果保证其他的管道类都可以获取item对象:
        - 每个管道类都return item:将item提交给下一个即将被执行的管道类
    

    1.基于终端指令的持久化存储

    1.基于终端指令的持久化存储
        - 只可以将parase方法的返回值存储到指定后缀的文本文件中
        - 存储指令:scrapy crwal 爬虫文件名 -o 储存文件路径
    

    spiders/qiubai.py

    import scrapy
    
    class QiubaiSpider(scrapy.Spider):
        name = 'qiubai'
        # allowed_domains = ['www.xxx.com']
        start_urls = ['https://www.qiushibaike.com/text/']
        all_list = []
        
        # 基于终端指令的持久化存储
        def parse(self, response):
            
            div_list = response.xpath('//*[@id="content"]/div/div[2]/div')
            for div in div_list:
                #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()返回的是列表
                content = div.xpath('./a[1]/div/span//text()').extract()
                content = ''.join(content)
                print(author,content)
                dic = {
                    'author':author,
                    'content':content
                }
                self.all_list.append(dic)
            return self.all_list
    

    执行项目

    scrapy crawl qiubai -o 1.csv
    
    

    2.基于管道的持久化存储(重点)

    2.基于管道的持久化存储(重点)
        - 在爬虫文件中进行数据解析
        - 在items文件中声明数据解析出的字段属性
        - 在爬虫文件中将解析出的字段存储封装到items类型的对象中
        - 将item对象提交给管道
        - 在管道文件pipelines.py的类中实现任意形式的持久化存储操作
    - 需要在配置文件中开启管道机制
        - 什么时候需要创建多个管道类?
        - 数据备份。一个管道类负责将数据存储到一种平台种。
    - 注意:爬虫文件提交过来的item只会给优先级最高的那一个管道类
        - 如果保证其他的管道类都可以获取item对象:
        - 每个管道类都return item:将item提交给下一个即将被执行的管道类
        
    redis-Windows安装:
        下载地址:https://github.com/tporadowski/redis/releases
         解压->cd到文件夹下:redis-server.exe redis.windows.conf
    
    

    spiders/qiubai.py

    import scrapy
    from qiubaiPro.items import QiubaiproItem # 引入items类
    
    class QiubaiSpider(scrapy.Spider):
        name = 'qiubai'
        # allowed_domains = ['www.xxx.com']
        start_urls = ['https://www.qiushibaike.com/text/']
    
    	# 基于管道持久化存储
        def parse(self, response):
            div_list = response.xpath('//*[@id="content"]/div/div[2]/div')
            for div in div_list:
                #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()返回的是列表
                content = div.xpath('./a[1]/div/span//text()').extract()
                content = ''.join(content)
    
                item = QiubaiproItem() # 实例化item对象,将解析出的值赋给item对象
                item['author']  = author
                item['content'] = content
    
                yield item # 将item对象提交给管道
    
    

    items.py

    import scrapy
    
    class QiubaiproItem(scrapy.Item):
        # define the fields for your item here like:
        # 声明两个字段
        author = scrapy.Field()
        content = scrapy.Field()
    
    
    

    settings.py

    ITEM_PIPELINES = {
        #300表示的是管道类的优先级,数值越小表示优先级越高
       'qiubaiPro.pipelines.QiubaiproPipeline': 300,
       'qiubaiPro.pipelines.MySqlPipeLine': 301,
       'qiubaiPro.pipelines.RedisPipeLine': 302,
    }
    
    

    pipelines.py

    import pymysql
    from redis import Redis
    
    # 将数据储存到本地文件
    class QiubaiproPipeline:
        fp = None
        def open_spider(self,spider):#在开始爬取数据的时候被调用一次
            print('i am open_spider()')
            self.fp = open('./qiubai.txt','w',encoding='utf-8')
    
        # 参数item就是管道接收到的item对象
        # 该方法的调用次数取决于爬虫文件提交item的次数
        def process_item(self, item, spider):
            self.fp.write(item['author']+':'+item['content']+'
    ')
            return item #将item提交给下一个即将被执行的管道类
    
        def close_spider(self,spider):#只会在爬虫结束时调用一次
            print('i am close_spider()')
            self.fp.close()
    
    # 定义管道类,负责将数据存储到mysql
    class MySqlPipeLine(object):
        conn =None
        cursor = None
        def open_spider(self,spider):
            # 创建连接
            self.conn = pymysql.Connect(host='127.0.0.1',port=3306,user='root',password='123456',db='qiushi',charset='utf8')
    
        def process_item(self,item,spider):
            # 创建游标对象
            self.cursor = self.conn.cursor()
            # sql语句插入数据
            sql = 'insert into qiubai values("%s","%s")'%(item['author'],item['content'])
            try:
                self.cursor.execute(sql) # 执行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() # 关闭连接
    
    # 定义管道类,负责将数据存储到redis
    # redis模块的版本2.10.6
    class RedisPipeLine(object):
        conn = None
        def open_spider(self,spider):
            # 建立连接
            self.conn = Redis(host='127.0.0.1',port=6379)
        def process_item(self,item,spider):
            self.conn.lpush('qiubaiQueue',item)
            return item
    
    
  • 相关阅读:
    Android 监听键盘的弹起与收缩
    Android Glide+CircleImageView实现加载圆形图片列表
    Java 集合
    Java 文件IO续
    Java 文件IO
    Java 网络编程
    Android AIDL Service
    Android 四大组件之Service
    Android 开源项目分类汇总(转)
    Android SQLite数据库
  • 原文地址:https://www.cnblogs.com/jia-shu/p/14695523.html
Copyright © 2020-2023  润新知