scrapy数据解析与scrapy数据的持久化存储

scrapy 数据解析

(1) extract_first() 与 extract() 函数的区别在于

  • extract 返回的数据是一个列表
  • extract_first 返回的数据不是一个列表数据
  • response.xpath(“””//[@id=”s-hotsearch-wrapper”]/div/a[1]/div”””)[0].extract() 返回的结果是与
    response.xpath(“””//
    [@id=”s-hotsearch-wrapper”]/div/a[1]/div”””).extract_first() 返回的结果是完全相同的

(2) xpath()中的text() 函数的使用,我这里使用一个简单的例子来说明这点:

  • response.xpath(“””//*[@id=”s-hotsearch-wrapper”]/div/a[1]/div”””)extract() 返回的结果是
    ‘’
  • response.xpath(“””//*[@id=”s-hotsearch-wrapper”]/div/a[1]/div/text()”””).extract() 返回的结果是
    [‘百度热榜’]

(3) extract_first() 与 extract() 相同点:

  • 两者返回的信息格式都是 selector 对象,及 scrapy 使用 xpath() 函数 进行数据筛选,将data 对象存储在 selector 对象中, selector 对象是一个list 的对象数据

scrapy 数据的持久化存储

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

  1. import scrapy
  2. class QiubaiSpider(scrapy.Spider):
  3. name = 'qiubai'
  4. allowed_domains = ['https://www.qiushibaike.com/']
  5. start_urls = ['https://www.qiushibaike.com/']
  6. def parse(self, response):
  7. #xpath为response中的方法,可以将xpath表达式直接作用于该函数中
  8. odiv = response.xpath('//div[@id="content-left"]/div')
  9. content_list = [] #用于存储解析到的数据
  10. for div in odiv:
  11. #xpath函数返回的为列表,列表中存放的数据为Selector类型的数据。我们解析到的内容被封装在了Selector对象中,需要调用extract()函数将解析的内容从Selecor中取出。
  12. author = div.xpath('.//div[@class="author clearfix"]/a/h2/text()')[0].extract()
  13. content=div.xpath('.//div[@class="content"]/span/text()')[0].extract()
  14. #将解析到的内容封装到字典中
  15. dic={
  16. '作者':author,
  17. '内容':content
  18. }
  19. #将数据存储到content_list这个列表中
  20. content_list.append(dic)
  21. return content_list
  • 需求: 该方法只可以将parse 方法 的返回值存储到本地制定的后缀名文件中。
  • 使用: 我这里提供了一个例子提供给学习参考
  1. scrapy crawl baidu --nolog -o baidu.json
  2. # baidu 为爬虫的名称
  3. # --nolog 为不打印日志信息
  4. # -o baidu.json 其中的 baidu.json 为 json 文件的名称, 其中导出的格式包括 ('json', 'jsonlines', 'jl', 'csv', 'xml', 'marshal', 'pickle')
  5. # 当输出结果是中文时,请在settings.py中 添加 `FEED_EXPORT_ENCODING = 'utf-8'`
  • (2) 基于管道的持久化存储(重点) ```python 爬虫文件:qiubaiDemo.py

import scrapy from secondblood.items import SecondbloodItem class QiubaidemoSpider(scrapy.Spider):    name = ‘qiubaiDemo’    allowed_domains = [‘www.qiushibaike.com’] start_urls = [‘http://www.qiushibaike.com/‘] def parse(self, response): odiv = response.xpath(‘//div[@id=”content-left”]/div’) for div in odiv:

# xpath函数返回的为列表,列表中存放的数据为Selector类型的数据。我们解析到的内容被封装在了Selector对象中,需要调用extract()函数将解析的内容从Selecor中取出。
    author = div.xpath('.//div[@class="author clearfix"]//h2/text()').extract_first()
    author = author.strip('\n')#过滤空行
    content = div.xpath('.//div[@class="content"]/span/text()').extract_first()
    content = content.strip('\n')#过滤空行
    #将解析到的数据封装至items对象中
    item = SecondbloodItem()
    item['author'] = author
    item['content'] = content
    yield item#提交item到管道文件(pipelines.py)

items文件:items.py

import scrapy class SecondbloodItem(scrapy.Item):

# define the fields for your item here like:
# name = scrapy.Field()
author = scrapy.Field() #存储作者
content = scrapy.Field() #存储段子内容


- (2.1) 爬虫文件中进行书记解析 
   - 使用xpath()函数进行数据操作/数据解析



-  (2.2) 在 items.py中进行相关属性打定义 
   - (2.2.1) 确定好属性值,及需要几个属性值
   - (2.2.2) 进行属性定义



-  (2.3) 在爬虫文件中通过解析到到文件/数据封装到 item 类型到对象中 
   - (2.3.1) 首先实例化一个 item 对象
   - (2.3.2) 不可以通过.来进行赋值,只能通过 [属性名]的方式进行赋值



-  (2.4) 在管道文件(pipelines.py)中, 接收爬虫文件传输过来到items 对象,且对其进行任何形式的持久化存储操作(核心操作) 
   - (2.4.1) 在相关爬虫文件(这里是baidu.py文件的 BaiduSpider 类中)函数 def parse(self, response, **kwargs) 添加 yield items, 其中 items 为 (2.3) 形成的数据
   - (2.4.2) 对管道文件(pipelines.py)进行书写 
      - (2.4.2.1)参数说明: 
         - item: 接收的item对象,其中 item 对象其实就是一个 dict(字典型) 的数据对象



      - (2.4.2.2)在接收 item 对象时,一次只能接收一个管道文件,说明该方法必须调用多次已实例化对象
      - (2.4.2.3)当保存到相关的文本文件或相关文件中 
         - (2.4.2.3.1)不能在 process_item 函数中进行open 操作,应该重写 父类中的两个方法 
            - (2.4.2.3.1.1) def open_spider(self, spider):打开文件的方法,只会在爬虫在最开始启动时候执行一次
            - (2.4.2.3.1.2) def close_spider(self, spider):关闭文件,只会在爬虫结束的时候执行一次
            - (2.4.2.3.1.3) 并且在 def process_item(self, item, spider) 中进行写入操作


```python
# 这是一个demo 案例
from itemadapter import ItemAdapter
class Day01Pipeline:
    fp = None

    # 打开文件的方法,只会在爬虫在最开始启动时候执行一次
    def open_spider(self, spider):
        self.fp = open("textile.txt", "w", encoding="utf-8")

    # 关闭文件,只会在爬虫结束的时候执行一次
    def close_spider(self, spider):
        self.fp.close()

    def process_item(self, item, spider):
        # 在接收 item 对象时,一次只能接收一个管道文件,说明该方法必须调用多次已实例化对象
        self.fp.write("写入内容")
        return item
  • (2.5) 在配置文件中开启管道机制

    • (2.5.1) 管道文件的相关配置在 settings.py 中 的 ITEM_PIPELINES 参数中,我这里提供了一个实例

      ITEM_PIPELINES = {
      'First.pipelines.Day01Pipeline': 300,
      }
      
      • 参数说明
        • 300 表示管道类的优先级, 数值越小,优先级越高,越先执行
        • 其中的 ITEM_PIPELINES 是一个字典型的数据格式
        • 其中的 ‘Day_01.pipelines.Day01Pipeline’ 表示管道文件的相关路径