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+"\n\n\n")
                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+"\n\n\n")
            
            #关闭爬虫会调用一次
            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,
}

 

posted @ 2019-02-19 14:20  丫丫625202  阅读(246)  评论(0编辑  收藏  举报