相关文件

items.py

数据结构模板文件。定义数据属性。

pipelines.py

管道文件。接收数据(items),进行持久化操作。

持久化流程

▨ 爬虫文件爬取到数据后,将数据封装到 items 对象 

▨  items.py  用  yield 关键字将 items对象 提交给 pipelines.py  

▨ 在管道文件中的  process_item  方法中接收 item对象 进行存储

▨  settings.py  配置文件中开启管道

持久化方式

文件保存 ( 普通文件 / csv / json  )

* scrapy crawl maoyan -o maoyan.csv
* scrapy crawl maoyan -o maoyan.json

导出时需要配合 settings.py 配置导出编码格式

FEED_EXPORT_ENCODING='utf-8'

ps:

  scrapy1.6版本之前, 导出csv出现空行, 

    解决方法(修改源码exporters.py)

Scrapy 框架,持久化文件相关

  路径 :python安装目录的Lib\site-packages\scrapy\exporters.py

  搜索 csv ,添加 newline='' 参数

数据库保存 ( redis / mongo / mysql )

详见下面实例

图片保存

官方文档  这里

pipline 设置

import scrapy
from scrapy.pipelines.images import ImagesPipeline


class MyImagesPipeline(ImagesPipeline):

    # 本质上就是拿到了 item 里面的 "image_urls" 字段的 url 地址然后再次发起请求带队列中
    # 重写get_media_requests方法, 指定图片持久化的字段
    def get_media_requests(self, item, info):
        yield scrapy.Request(item['img_link'])  # 这里指定 item 中要被图片持久的字段

    # 此函数用于处理拿到请求后的数据时的异常以及其他操作, 比如这里实现的操作就是拿到 url 后保存在了 item 的 image_file_path 字段中
    # 重写此函数可以拿到 图片的 地址, 用于数据库保存等
    def item_completed(self, results, item, info):
        for ok, value in results:
            image_file_path = value["path"]
        item['image_file_path'] = image_file_path
        return item

 

配置设置

使用内置的 图片管道, 需要在 settings.py  中设置保存路径以及大小限制

ITEM_PIPELINES = {'xxxx.pipelines.MyImagesPipeline': 1}
import os

project_dir = os.path.abspath(os.path.dirname(__file__))
IMAGES_STORE = os.path.join(project_dir, "images")

IMAGES_MIN_HEIGHT
= 110 # 最小高 IMAGES_MIN_WIDTH = 110 # 最小宽

源码位置

Scrapy 框架,持久化文件相关

综合实例 - 文件存入

爬虫文件

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[@>)
        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() # 存储段子内容

管道文件

pipelines.py

from scrapy.exceptions import DropItem

class SecondbloodPipeline(object):

    def __init__(self,path):
        self.f = None
        self.path = path    
        # 写入文件的路径参数 ,放在 setting 中了。
        # 通过 from_crawler 来拿到 path 

    @classmethod
    def from_crawler(cls, crawler): 
        """
        初始化时候,用于创建pipeline对象
        """
        print('File.from_crawler')
        path = crawler.settings.get('HREF_FILE_PATH') 
        return cls(path)

    def open_spider(self,spider):
        """
        爬虫开始执行时,调用 
        用于 文件的打开
        """
        # if spider.name == "chouti":  # spider参数 用于筛选个性化定制 
        print('File.open_spider')
        self.f = open(self.path,'a+')

    def process_item(self, item, spider):
        # f = open('xx.log','a+')
        # f.write(item['href']+'\n')
        # f.close() 
        # 这样写太low了,每次都要打开关闭文件
        # 因此选择 将 文件操作绕开每次循环。
        print('File',item['author'])
        print('File',item['content'])
        self.f.write(item['author'] + ':' + item['content'] + '\n')
        
        # return item      # 交给下一个pipeline的process_item方法
        raise DropItem()# 后续的 pipeline的process_item方法不再执行

    def close_spider(self,spider):
        """
        爬虫关闭时,被调用
        用于 文件的关闭 
        """
        print('File.close_spider')
        self.f.close()

 注意:pipeline 是所有爬虫公用,如果想要给某个爬虫定制需要使用spider参数自己进行处理

ps:

数据的处理当然可以写入 数据库,或者 redis 如下实例

# -*- coding: utf-8 -*-
# Define your item pipelines here
# Don't forget to add your pipeline to the ITEM_PIPELINES setting
# See: https://doc.scrapy.org/en/latest/topics/item-pipeline.html

#导入数据库的类
import pymysql
 
class QiubaiproPipelineByMysql(object):
    conn = None  #mysql的连接对象声明
    cursor = None#mysql游标对象声明
    def open_spider(self,spider):
        print('开始爬虫')
        #链接数据库
        self.conn = pymysql.Connect(host='127.0.0.1',port=3306,user='root',password='123456',db='qiubai')
    
    #编写向数据库中存储数据的相关代码
    def process_item(self, item, spider):
        #1.链接数据库
        #2.执行sql语句
        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):
        print('爬虫结束')
        self.cursor.close()
        self.conn.close()
MySQL 的数据处理

相关文章:

  • 2021-10-02
  • 2022-12-23
  • 2022-12-23
  • 2021-11-07
  • 2021-11-19
  • 2021-06-13
猜你喜欢
  • 2021-07-15
  • 2022-12-23
  • 2022-12-23
  • 2021-11-11
  • 2021-07-02
  • 2021-09-11
  • 2022-12-23
相关资源
相似解决方案