• scrapy基础使用


    编辑本随笔

    简介:

    Scrapy:为了爬去网站数据而编写的一款应用框架,即集成了相应功能且具有很强通用性的项目模板。

    功能:

    1. 高性能异步下载
    2. 解析操作
    3. 持久化存储等
    4. 代理和cookie
    5. 日志等级和请求传参
    6. CrawlSpider
    7. 基于redis的分布式爬虫

    安装:linux用pip install scrapy安装即可,win安装查找其他资料

    基础使用:

    1.创建一个工程

    命令:scrapy startproject firstBlood

    目录结构:

     

    pipelines.py 处理数据持久化处理相关操作

    items.py 设置数据存储模板,用于结构化数据,入django的model

    scrapy.cfg 项目主配置文件(无需修改)

    settings.py 配置文件

    spiders 爬虫目录,使用scrapy genspider命令创建的文件会存放在这里

    2.在工程目录下创建一个爬虫文件

    1. 进入工程目录
    2. scrapy genspider 爬虫文件名称 起始url
    3. scrapy genspider qiushibaike https://www.qiushibaike.com/
      import scrapy
      class FirstSpider(scrapy.Spider):
          #爬虫文件的名称:可以通过爬虫文件的名称定位到某一个具体的爬虫文件
          name="qiushibaike"
          
          #允许的域名:只可以爬去指定域名下的页面数据
          allowed_domains=['www.qiushibaike.com']
          
          #起始url:当前工程将要爬取的页面对应的url,可以添加多个url,但需符合allowed_domains
          start_urls=["https://www.qiushibaike.com/"]
          
          #解析方法:当执行工程的时候,获取的页面数据将由parse方法来负责解析
          def parse(self,response):
              #response:根据起始url列表发起请求,请求成功后返回的响应对象
              #parse的返回值必须为迭代器对象或者空
              #获取响应页面中的页面数据
              page_text=response.text
              print(page_text)

    3.编写配置文件

    #不遵循robots协议
    ROBOTSTXT_OBEY=False
    
    #对请求身份进行伪装
    USER_AGENT="Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:65.0) Gecko/20100101 Firefox/65.0"

    4.启动

    scrapy crawl 文件名称
    #参数:
      --nolog 禁用日志输

     

    数据解析

    需求:爬取糗事百科中段子内容和作者

    • 创建一个工程:scrapy startproject qiubaiPro
    • 创建爬虫文件:
      • cd qiubaiPro
      • scrapy genspider qiubai www.qiushibaike.com/text
    • 编写爬虫文件:数据解析建议使用xpath,scrapy已经集成xpath接口
      # -*- coding: utf-8 -*-
      import scrapy
      
      class QiubaiSpider(scrapy.Spider):
          name = 'qiubai'
          allowed_domains = ['www.qiushibaike.com/text']
          start_urls = ['http://www.qiushibaike.com/text/']
      
          def parse(self, response):
              div_list=response.xpath("//div[@id='content-left']/div")
              for div in div_list:
                  author=div.xpath("./div/a[2]/text()")
                  #非直系节点,用//
                  content=div.xpath(".//div[@class='content']/span/text()")
    • 配置文件编写,禁用ROBOTSTXT协议,修改User-Agent
    • 执行工程 

    数据持久化

    存储方式:

    存储到磁盘

    1. 基于终端指令存储
      • parse返回一个可迭代类型的对象(存储解析到的页面内容)
      • 使用终端指令完成数据存储到指定磁盘文件中的操作 scrapy crawl qiubai -o qiubai.csv --nolog
        # -*- coding: utf-8 -*-
        import scrapy
        
        
        class QiubaiSpider(scrapy.Spider):
            name = 'qiubai'
            #allowed_domains = ['www.qiushibaike.com']
            start_urls = ['https://www.qiushibaike.com/text/']
        
            def parse(self, response):
                div_list=response.xpath("//div[@id='content-left']/div")
                
                #用于返回可迭代器对象
                data_list=[]
                
                for div in div_list:
                    
                    #xpath解析到的指定内容被存储到了selecter对象,可以用extract()方法提取数据值
                    #author=div.xpath("./div/a[2]/h2/text()").extract()[0]
                    
                    #推荐使用extract_first()方法,extract()[0]会可能会出错,如没有获取到内容就会出现index错误
                    author=div.xpath("./div/a[2]/h2/text()").extract_first()
                    
                    #非直系节点,用//
                    content=div.xpath(".//div[@class='content']/span/text()").extract()[0]
                    
                    data_dict={
                        "author":author,
                        "content":content
                    }
                    data_list.append(data_dict)
                return data_list
        View Code

         

    2. 基于管道存储
      • 代码实现流程
        • 将解析到的页面数据,存储到items中
          import scrapy
          from qiubaiPro.items import QiubaiproItem
          class QiubaiSpider(scrapy.Spider):
              name = 'qiubai'
              #allowed_domains = ['www.qiushibaike.com']
              start_urls = ['https://www.qiushibaike.com/text/']
          
              def parse(self, response):
                  div_list=response.xpath("//div[@id='content-left']/div")
                  
                  for div in div_list:
                      #推荐使用extract_first()方法,extract()[0]会可能会出错,如没有获取到内容就会出现index错误
                      author=div.xpath("./div/a[2]/h2/text()").extract_first()
                      
                      #非直系节点,用//
                      content=div.xpath(".//div[@class='content']/span/text()").extract()[0]
                      
                      item=QiubaiproItem()
                      item["author"]=author
                      item["content"]=content
                      
                      #将item对象用yield提交给管道文件
                      yield item
          View Code
          #items.py文件
          import scrapy
          class QiubaiproItem(scrapy.Item):
              # define the fields for your item here like:
              # name = scrapy.Field()
              author=scrapy.Field()
              content=scrapy.Field()
          View Code
        • 使用yield将items对象提交给管道文件进行处理
        • 在pipelines文件中编写代码完成数据存储相关的操作
          #pipelines文件
          class QiubaiproPipeline(object):
              #接收爬虫文件提交过来的item对象,并且对item对象中存储的页面数据进行持久化操作
              #参数:item:接收到的item对象
              def process_item(self, item, spider):
                  author=item["author"]
                  content=item["content"]
                  with open("./qiubai_pipe.txt","w",encoding="utf-8") as fp:
                      fp.write(author+":"+content+"
          
          
          ")
                  return item
          View Code
        •  修改版的pipelines.py

          #pipelines.py
          class QiubaiproPipeline(object):
              fp=None
              #在整个爬虫过程中,该方法只会在爬虫开始的时候调用一次
              def open_spider(self,spider):
                  self.fp=open("./qiubai_pipe.txt","w",encoding="utf-8")
                  
              #接收爬虫文件提交过来的item对象,并且对item对象中存储的页面数据进行持久化操作
              #参数:item:接收到的item对象
              #每当爬虫给管道提交一次item,则该方法执行一次
              def process_item(self, item, spider):
                  author=item["author"]
                  content=item["content"]
                  self.fp.write(author+":"+content+"
          
          
          ")
              
              #关闭爬虫会调用一次
              def close_spider(self,spider):
                  self.fp.close()
          View Code
        • 在配置文件中开启管道操作,然后启动爬虫操作 scrapy crawl qiubai --nolog
          #settings.py文件
          # See https://doc.scrapy.org/en/latest/topics/item-pipeline.html
          #300表示优先级
          ITEM_PIPELINES = {
             'qiubaiPro.pipelines.QiubaiproPipeline': 300,
          }
          View Code

    存储到数据库

    编码流程:

    • 将解析到的页面数据,存储到items中
    • 使用yield将items对象提交给管道文件进行处理
    • 在pipelines文件中编写代码完成数据存储相关的操作
    • 在配置文件中开启管道操作,然后启动爬虫操作 scrapy crawl qiubai --nolog

    mysql存储pipelines文件编写

    #pipelines.py
    import pymysql
    class QiubaiproPipeline(object):
        #编写想数据库中存储数据的相关代码
        conn=None
        #链接数据库
        def open_spider(self,spider):
            self.conn=pymysql.Connect(host="127.0.0.1",port=3306,user="root",password="123456.com",db="qiubai")
        
        def process_item(self, item, spider):
            SQL="insert into qiubai values('%s','%s')" % (item['author'],item['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()
    View Code

    redis存储pipelines文件编写

    import redis
    class QiubaiproPipeline(object):
        #编写想数据库中存储数据的相关代码
        conn=None
        #链接redis数据库
        def open_spider(self,spider):
            self.conn=redis.Redis(host="127.0.0.1",port=6379)
        
        def process_item(self, item, spider):
            data={
                "author":item["author"],
                "content":item["content"]
            }
            self.conn.lpush("qiubai",data)
            return item
        
        #关闭链接
        def close_spider(self,spider):
            self.conn.close()
    View Code

    数据存储到多个平台

    在pipelines文件中自定义处理类管道类

    #数据存储到本地文件中
    class QiuBaiByFiles(object):
        def process_item(self, item, spider):
            print("写入到文件中")
            return item
        
    #数据存储到MySQL数据库中
    class QiuBaiByMysql(object):
        def process_item(self, item, spider):
            print("写入到MySQL中")
            return item
        
    #数据存储到Redis数据库中
    class QiuBaiByRedis(object):
        def process_item(self, item, spider):
            print("写入到Redis中")
            return item

    在settings.py文件中注册处理类

    ITEM_PIPELINES = {
    #    'qiubaiPro.pipelines.QiubaiproPipeline': 300,
       'qiubaiPro.pipelines.QiuBaiByFiles': 300,
       'qiubaiPro.pipelines.QiuBaiByMysql': 400,
       'qiubaiPro.pipelines.QiuBaiByRedis': 500,
    }

  • 相关阅读:
    python多线程爬虫:亚马逊价格
    python在linux中输出带颜色的文字的方法
    单线程爬虫VS多线程爬虫的效率对比
    python爬虫:正则表达式
    爬虫-python调用百度API/requests
    Python gevent学习笔记-2
    Python gevent学习笔记
    IO多路复用之select总结
    select、poll、epoll之间的区别总结[整理]
    2020年 IEDA破解码失效,2019 版IDEA无法使用 ,已解决,有效期2100年;原标题:IDEA激活—免费永久激活(lookdiv.com)
  • 原文地址:https://www.cnblogs.com/yaya625202/p/10400807.html
Copyright © 2020-2023  润新知