《零基础实践深度学习》2.3.3 校验数据有效性 基于飞桨Dataset和DataLoader API完成数据处理

简介: 这篇文章详细介绍了在深度学习任务中进行数据处理的步骤,包括数据校验、封装数据读取与处理函数、使用飞桨Dataset和DataLoader API完成数据加载,以及数据增强/增广的方法和实践,旨在确保数据的有效性和提高模型训练效果。

2.3.3 校验数据有效性

在实际应用中,原始数据可能存在标注不准确、数据杂乱或格式不统一等情况。因此在完成数据处理流程后,还需要进行数据校验,一般有两种方式:

  • 机器校验:加入一些校验和清理数据的操作
  • 人工校验:先打印数据输出结果,观察是否是设置的格式。再从训练的结果验证数据处理和读取的有效性

2.3.3.1 机器校验

如下代码所示,如果数据集中的图片数量和标签数量不等,说明数据逻辑存在问题,可使用assert语句校验图像数量和标签数据是否一致。

In [5]

imgs_length = len(imgs)
assert len(imgs) == len(labels), \
        "length of train_imgs({}) should be the same as train_labels({})".format(len(imgs), len(labels))

2.3.3.2 人工校验

人工校验是指打印数据输出结果,观察是否是预期的格式。实现数据处理和加载函数后,我们可以调用它读取一次数据,观察数据的形状和类型是否与函数中设置的一致。

In [6]

# 声明数据读取函数,从训练集中读取数据
train_loader = data_generator
# 以迭代的形式读取数据
for batch_id, data in enumerate(train_loader()):
    image_data, label_data = data
    if batch_id == 0:
        # 打印数据shape和类型
        print("打印第一个batch数据的维度,以及数据的类型:")
        print("图像维度: {}, 标签维度: {}, 图像数据类型: {}, 标签数据类型: {}".format(image_data.shape, label_data.shape, type(image_data), type(label_data)))
    break

打印第一个batch数据的维度,以及数据的类型:

图像维度: (100, 784), 标签维度: (100,), 图像数据类型: <class 'numpy.ndarray'>, 标签数据类型: <class 'numpy.ndarray'>

2.3.4 封装数据读取与处理函数

上文我们从读取数据、划分数据集、到打乱训练数据、构建数据读取器以及数据数据校验,完成了一整套一般性的数据处理流程,下面将这些步骤放在一个函数中实现,方便在神经网络训练时直接调用。

In [7]

def load_data(mode='train'):
    datafile = './work/mnist.json.gz'
    print('loading mnist dataset from {} ......'.format(datafile))
    # 加载json数据文件
    data = json.load(gzip.open(datafile))
    print('mnist dataset load done')
   
    # 读取到的数据区分训练集,验证集,测试集
    train_set, val_set, eval_set = data
    if mode=='train':
        # 获得训练数据集
        imgs, labels = train_set[0], train_set[1]
    elif mode=='valid':
        # 获得验证数据集
        imgs, labels = val_set[0], val_set[1]
    elif mode=='eval':
        # 获得测试数据集
        imgs, labels = eval_set[0], eval_set[1]
    else:
        raise Exception("mode can only be one of ['train', 'valid', 'eval']")
    print("训练数据集数量: ", len(imgs))
    
    # 校验数据
    imgs_length = len(imgs)
    assert len(imgs) == len(labels), \
          "length of train_imgs({}) should be the same as train_labels({})".format(len(imgs), len(labels))
    
    # 获得数据集长度
    imgs_length = len(imgs)
    
    # 定义数据集每个数据的序号,根据序号读取数据
    index_list = list(range(imgs_length))
    # 读入数据时用到的批次大小
    BATCHSIZE = 100
    
    # 定义数据生成器
    def data_generator():
        if mode == 'train':
            # 训练模式下打乱数据
            random.shuffle(index_list)
        imgs_list = []
        labels_list = []
        for i in index_list:
            # 将数据处理成希望的类型
            img = np.array(imgs[i]).astype('float32')
            label = np.array(labels[i]).astype('float32')
            imgs_list.append(img) 
            labels_list.append(label)
            if len(imgs_list) == BATCHSIZE:
                # 获得一个batchsize的数据,并返回
                yield np.array(imgs_list), np.array(labels_list)
                # 清空数据读取列表
                imgs_list = []
                labels_list = []
    
        # 如果剩余数据的数目小于BATCHSIZE,
        # 则剩余数据一起构成一个大小为len(imgs_list)的mini-batch
        if len(imgs_list) > 0:
            yield np.array(imgs_list), np.array(labels_list)
    return data_generator

下面定义一层神经网络,利用定义好的数据处理函数,完成神经网络的训练

In [8]

# 数据处理部分之后的代码,数据读取的部分调用Load_data函数
# 定义网络结构,同上一节所使用的网络结构
class MNIST(paddle.nn.Layer):
    def __init__(self):
        super(MNIST, self).__init__()
        # 定义一层全连接层,输出维度是1
        self.fc = paddle.nn.Linear(in_features=784, out_features=1)
    def forward(self, inputs):
        outputs = self.fc(inputs)
        return outputs

In [9]

# 训练配置,并启动训练过程
def train(model):
    model = MNIST()
    model.train()
    #调用加载数据的函数
    train_loader = load_data('train')
    opt = paddle.optimizer.SGD(learning_rate=0.001, parameters=model.parameters())
    EPOCH_NUM = 10
    for epoch_id in range(EPOCH_NUM):
        for batch_id, data in enumerate(train_loader()):
            #准备数据,变得更加简洁
            images, labels = data
            images = paddle.to_tensor(images)
            labels = paddle.to_tensor(labels) 
            #前向计算的过程
            predits = model(images)
            
            #计算损失,取一个批次样本损失的平均值
            loss = F.square_error_cost(predits, labels)
            avg_loss = paddle.mean(loss)      
            
            #每训练了200批次的数据,打印下当前Loss的情况
            if batch_id % 200 == 0:
                print("epoch: {}, batch: {}, loss is: {}".format(epoch_id, batch_id, avg_loss.numpy()))
            
            #后向传播,更新参数的过程
            avg_loss.backward()
            opt.step()
            opt.clear_grad()
    # 保存模型
    paddle.save(model.state_dict(), './mnist.pdparams')
# 创建模型           
model = MNIST()
# 启动训练过程
train(model)

loading mnist dataset from ./work/mnist.json.gz ......

mnist dataset load done

训练数据集数量: 50000

epoch: 0, batch: 0, loss is: [15.857997]

epoch: 0, batch: 200, loss is: [9.080583]

epoch: 0, batch: 400, loss is: [9.78436]

epoch: 1, batch: 0, loss is: [7.9140673]

epoch: 1, batch: 200, loss is: [9.839129]

epoch: 1, batch: 400, loss is: [8.720339]...

epoch: 9, batch: 0, loss is: [9.359872]

epoch: 9, batch: 200, loss is: [9.66635]

epoch: 9, batch: 400, loss is: [6.984814]

2.3.5 基于飞桨Dataset和DataLoader API完成数据处理

上面我们对数据划分、训练样本乱序、生成批次数据以及如何封装数据读取与处理函数进行了详细的介绍。在飞桨框架中,可通过如下两个核心步骤完成数据集的定义与加载。

2.3.5.1 定义数据集

将磁盘中保存的原始图片、文字等样本和对应的标签映射到Dataset,方便后续通过索引index读取数据,在Dataset中还可以进行一些数据变换、数据增广等预处理操作。在飞桨框架中推荐使用paddle.io.Dataset自定义数据集,另外在paddle.vision.datasetspaddle.text目录下飞桨内置了一些经典数据集方便直接调用。

2.3.5.2 迭代读取数据集

自动将数据集的样本进行分批、乱序等操作,方便训练时迭代读取,同时还支持多进程异步读取功能可加快数据读取速度。在飞桨框架中可使用paddle.io.DataLoader迭代读取数据集。对于样本量较大、数据读取较慢的场景,建议采用异步数据读取方式。异步读取数据时,数据读取和模型训练并行执行,从而加快了数据读取速度,牺牲一小部分内存换取数据读取效率的提升,二者关系如图4所示。

图4:同步数据读取和异步数据读取示意图

(1)同步数据读取:数据读取与模型训练行。当模型需要数据时,才运行数据读取函数获得当前批次的数据。在读取数据期间,模型一直等待数据读取结束才进行训练,数据读取速度相对较慢。

(2)异步数据读取:数据读取和模型训练行。读取到的数据不断的放入缓存区,无需等待模型训练就可以启动下一轮数据读取。当模型训练完一个批次后,不用等待数据读取过程,直接从缓存区获得下一批次数据进行训练,从而加快了数据读取速度。

(3)异步队列:数据读取和模型训练交互的仓库,二者均可以从仓库中读取数据,它的存在使得两者的工作节奏可以解耦

通过飞桨paddle.io.Datasetpaddle.io.DataLoader两个API可以轻松创建异步数据读取的迭代器。

接下来我们具体来看如何借助这两个API轻松完成上述功能,具体代码如下:

In [10]

import json
import gzip
import paddle
from paddle.vision.transforms import Normalize
from paddle.io import Dataset
# 定义图像归一化处理方法,这里的CHW指图像格式需为 [C通道数,H图像高度,W图像宽度]
transform = Normalize(mean=[127.5], std=[127.5], data_format='CHW')
class MNISTDataset(Dataset):
    """
    步骤一:继承paddle.io.Dataset类
    """
    
    def __init__(self, datafile, mode='train', transform = None):
        """
        步骤二:实现构造函数
        """
        super().__init__()
        self.mode = mode
        self.transform = transform
        print('loading mnist dataset from {} ......'.format(datafile))
        # 加载json数据文件
        data = json.load(gzip.open(datafile))
        print('mnist dataset load done')
   
        # 读取到的数据区分训练集,验证集,测试集
        train_set, val_set, eval_set = data
        if mode=='train':
            # 获得训练数据集
            self.imgs, self.labels = train_set[0], train_set[1]
        elif mode=='valid':
            # 获得验证数据集
            self.imgs, self.labels = val_set[0], val_set[1]
        elif mode=='test':
            # 获得测试数据集
            self.imgs, self.labels = eval_set[0], eval_set[1]
        else:
            raise Exception("mode can only be one of ['train', 'valid', 'test']")
    
    def __getitem__(self, index):
        """
        步骤三:实现__getitem__方法,定义指定index时如何获取数据
        """
        data = self.imgs[index]
        label = self.labels[index]
        return self.transform(data),label
    def __len__(self):
        """
        步骤四:实现__len__方法,返回数据集总数目
        """
        return len(self.imgs)
datafile = './work/mnist.json.gz'
# 下载数据集并初始化 DataSet
train_dataset = MNISTDataset(datafile, mode='train', transform=transform)
test_dataset = MNISTDataset(datafile, mode='test', transform=transform)
print('train images: ', train_dataset.__len__(), ', test images: ', test_dataset.__len__())

loading mnist dataset from ./work/mnist.json.gz ......

mnist dataset load done

loading mnist dataset from ./work/mnist.json.gz ......

mnist dataset load done

train images: 50000 , test images: 10000

另外可通过transform字段传入一些对图像进行变换的操作,飞桨在paddle.vision.transforms下提供了一些常用的图像变换操作,如对图像进行中心裁剪、水平翻转图像和对图像进行归一化等。

完成数据集初始化之后,可以使用下面的代码打印数据的shape。

In [11]

from matplotlib import pyplot as plt
for data in train_dataset:
    image, label = data
    print('shape of image: ',image.shape)
    plt.title(str(label))
    plt.imshow(image[0])    
    break

/opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages/matplotlib/__init__.py:107: DeprecationWarning: Using or importing the ABCs from 'collections' instead of from 'collections.abc' is deprecated, and in 3.8 it will stop working

from collections import MutableMapping

/opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages/matplotlib/rcsetup.py:20: DeprecationWarning: Using or importing the ABCs from 'collections' instead of from 'collections.abc' is deprecated, and in 3.8 it will stop working

from collections import Iterable, Mapping

/opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages/matplotlib/colors.py:53: DeprecationWarning: Using or importing the ABCs from 'collections' instead of from 'collections.abc' is deprecated, and in 3.8 it will stop working

from collections import Sized

shape of image: (1, 1, 784)

/opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages/matplotlib/cbook/__init__.py:2349: DeprecationWarning: Using or importing the ABCs from 'collections' instead of from 'collections.abc' is deprecated, and in 3.8 it will stop working

if isinstance(obj, collections.Iterator):

/opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages/matplotlib/cbook/__init__.py:2366: DeprecationWarning: Using or importing the ABCs from 'collections' instead of from 'collections.abc' is deprecated, and in 3.8 it will stop working

return list(data) if isinstance(data, collections.MappingView) else data

/opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages/matplotlib/image.py:425: DeprecationWarning: np.asscalar(a) is deprecated since NumPy v1.16, use a.item() instead

a_min = np.asscalar(a_min.astype(scaled_dtype))

/opt/coda/envs/python35-paddle120-env/lib/python3.7/site-packages/matplotlib/image.py:426: DeprecationWarning: np.asscalar(a) is deprecated since NumPy v1.16, use a.item() instead

a_max = np.asscalar(a_max.astype(scaled_dtype))

在定义完paddle.io.Dataset后,使用paddle.io.DataLoaderAPI即可实现异步数据读取,数据会由Python线程预先读取,并异步送入一个队列中,并且可自动完成划分 batch 的工作。

classpaddle.io.DataLoader(dataset, batch_size=100, shuffle=True, num_workers=2)

DataLoader返回一个迭代器,迭代的返回dataset中的数据内容;

dataset是支持map-style的数据集(可通过下标索引样本),map-style的数据集请参考paddle.io.DatasetAPI。

使用paddle.io.DataLoaderAPI以batch的方式进行迭代数据,代码如下:

In [4]

# 定义并初始化数据读取器
train_loader = paddle.io.DataLoader(train_dataset, batch_size=64, shuffle=True, 
                                    num_workers=1, 
                                    drop_last=True)
print('step num:',len(train_loader))

step num: 781

通过上述方法,初始化了一个数据读取train_loader,用于加载训练数据集。在数据读取器中几个常用的字段如下:

  • batch_size:每批次读取样本数,示例中 batch_size=64 表示每批次读取 64 个样本。
  • shuffle:样本乱序,示例中 shuffle=True 表示在取数据时打乱样本顺序,以减少过拟合发生的可能。
  • drop_last:丢弃不完整的批次样本,示例中 drop_last=True 表示丢弃因数据集样本数不能被 batch_size 整除而产生的最后一个不完整的 batch 样本。
  • num_workers:同步/异步读取数据,通过 num_workers 来设置加载数据的子进程个数,num_workers的值设为大于0时,即开启多进程方式异步加载数据,可提升数据读取速度。

为了方便后续过程对数据的使用,将数据处理过程封装data_process.py中,后面小节直接调用该文件的实现即可。

数据处理完成后,接下来让我们开始模型训练:

数据迭代器train_loader在每次迭代时的数据shape为[batch_size, 1, 28, 28],因此需要将该数据形 式reshape为向量形式。

In [6]

def train(model):
    print('train:')
    model.train()
    opt = paddle.optimizer.SGD(learning_rate=0.001, parameters=model.parameters())
    EPOCH_NUM = 3
    for epoch_id in range(EPOCH_NUM):
        print('epoch:',epoch_id)
        for batch_id, data in enumerate(train_loader()):
            images, labels = data
            images = paddle.to_tensor(images).astype('float32')
            labels = paddle.to_tensor(labels).astype('float32')
            
            images = paddle.reshape(images, [images.shape[0], images.shape[2]*images.shape[3]])
            #前向计算的过程  
            predicts = model(images)
            #计算损失,取一个批次样本损失的平均值
            loss = F.square_error_cost(predicts, labels)
            avg_loss = paddle.mean(loss)       
            
            #每训练了200批次的数据,打印下当前Loss的情况
            if batch_id % 200 == 0:
                print("epoch: {}, batch: {}, loss is: {}".format(epoch_id, batch_id, avg_loss.numpy()))
            
            #后向传播,更新参数的过程
            avg_loss.backward()
            opt.step()
            opt.clear_grad()
    #保存模型参数
    paddle.save(model.state_dict(), 'mnist.pdparams')
#创建模型
print("create model:")
model = MNIST()
#启动训练过程
train(model)

create model:

train:

epoch: 0

epoch: 0, batch: 0, loss is: [33.800125]

epoch: 0, batch: 200, loss is: [15.026532]

epoch: 0, batch: 400, loss is: [7.312279]

epoch: 0, batch: 600, loss is: [8.8055935].......

epoch: 2

epoch: 2, batch: 0, loss is: [10.347084]

epoch: 2, batch: 200, loss is: [7.91061]

epoch: 2, batch: 400, loss is: [9.701729]

epoch: 2, batch: 600, loss is: [8.192236]

2.3.6 数据增强/增广

任何数学技巧都不能弥补信息的缺失-Cornelius Lanczos(匈牙利数学家、物理学家)

本节介绍的各种数据处理方法仅限于为了实现深度学习任务,所必要的数据处理流程。但在实际任务中,原始数据集未必完全含有解决任务所需要的充足信息。这时候,通过分析任务场景,有针对性的做一些数据增强/增广的策略,往往可以显著的提高模型效果。

数据增强是一种挖掘数据集潜力的方法,可以让数据集蕴含更多让模型有效学习的信息。这些方法是领域和任务特定的,通过分析任务场景的复杂性和当前数据集的短板,对现有数据做有针对性的修改,以提供更加多样性的、匹配任务场景复杂性的新数据。下面以计算机视觉相关问题的数据增强为例,给读者一些具体增强方法和背后的思考。

2.3.6.1 基础的数据增强/增广方法和实践

图5所示为一些基础的图像增强方法,如果我们发现数据集中的猫均是标准姿势,而真实场景中的猫时常有倾斜身姿的情况,那么在原始图片数据的基础上采用旋转的方法造一批数据加入到数据集会有助于提升模型效果。类似的,如果数据集中均是高清图片,而真实场景中经常有拍照模糊或曝光异常的情况,则采用降采样和调整饱和度的方式造一批数据,回有助于提升模型的效果。

图5:基础的图像增强方法

接下来我们通过几个简单的小demo展示如何基于paddle.vision.transforms实现上述变换。

(1)亮度调整

In [13]

import numpy as np
from PIL import Image
from paddle.vision.transforms import functional as F
img_path = "/home/aistudio/work/cat.jpg"
image=Image.open(img_path)
# adjust_brightness对输入图像进行亮度值调整
new_img = F.adjust_brightness(image, 0.4)
# 显示图像
display(image.resize((300,400)))
display(new_img.resize((300,400)))

<PIL.Image.Image image mode=RGB size=300x400 at 0x7F9FA8D7A690>

<PIL.Image.Image image mode=RGB size=300x400 at 0x7F9FA961C910>

(2)色调调整

In [14]

import numpy as np
from PIL import Image
from paddle.vision.transforms import functional as F
img_path = "/home/aistudio/work/cat.jpg"
image=Image.open(img_path)
# adjust_hue对输入图像进行色调的调整
F.adjust_hue(image, 0.1)
# 显示图像
display(image.resize((300,400)))
display(new_img.resize((300,400)))

<PIL.Image.Image image mode=RGB size=300x400 at 0x7FA1289856D0>

<PIL.Image.Image image mode=RGB size=300x400 at 0x7F9FA9673490>

(3)随机旋转

In [15]

import numpy as np
from PIL import Image
from paddle.vision.transforms import RandomRotation
img_path = "/home/aistudio/work/cat.jpg"
image=Image.open(img_path)
# RandomRotation依据90度,按照均匀分布随机产生一个角度对图像进行旋转
transform = RandomRotation(90)
new_img = transform(image)
# 显示图像
display(image.resize((300,400)))
display(new_img.resize((300,400)))

<PIL.Image.Image image mode=RGB size=300x400 at 0x7F9FA8D98A90>

<PIL.Image.Image image mode=RGB size=300x400 at 0x7F9FA8DB0BD0>

2.3.6.2 高阶的数据增强/增广方法和实践

图6展示了一些高阶的图像增强方法,裁剪和拼接分别适合于“数据集中物体完整,但实际场景中物体存在遮挡”,以及“数据集中物体背景单一,而实际场景中物体的背景多变”的两种情况。具体数据增广实现,参见PaddleClas

图6:高阶的图像增强方法

(1)文本识别的数据增强方法

图7展示了专门针对文本识别的数据增强方法TIA(Text Image augmentation),对应到“数据集中字体多是平面,而真实场景中的字体往往会在曲面上扭曲的情况,比如拿着相机对一张凸凹不平摆放的纸面拍摄的文字就会存在该效果”。

图7:文本识别数据增强方法

(2)一种新颖的数据增强技巧CopyPaste

现实中的文字检测要面临复杂多样的背景,比如店铺牌匾上的文字周围的背景可能是非常多样的。我们将部分文本区域剪辑出来,随机摆放到图片的各种位置来生成数据用于训练,会大大提高模型在复杂背景中,检测到文字内容的能力

图8:一种新颖的数据增强技巧CopyPaste

由上述案例可见,数据增强/增广的方法是要根据实际领域和任务来进行设计的,在本书后续更深度的章节我们会展示如何基于飞桨来实现各种数据增强方法。在当前,读者仅需要了解,在深度学习任务的数据处理流程中常要采用这样的技巧。手写数字识别的任务比较简单,数据集也相对规整,并没有必要采用这些方法。

相关文章
|
12天前
|
JSON API 数据格式
Python 请求微店商品详情数据 API 接口
微店开放平台允许开发者通过API获取商品详情数据。使用Python请求微店商品详情API的主要步骤包括:1. 注册并申请API权限,获得app_key和app_secret;2. 确定API接口地址与请求参数,如商品ID;3. 生成签名确保请求安全合法;4. 使用requests库发送HTTP请求获取数据;5. 处理返回的JSON格式响应数据。开发时需严格遵循微店API文档要求。
|
12天前
|
缓存 监控 API
微店商品详情API接口实战指南:从零实现商品数据自动化获取
本文介绍了微店商品详情API接口的应用,涵盖申请与鉴权、签名加密、数据解析等内容。通过Python实战演示了5步获取商品数据的流程,并提供了多平台同步、价格监控等典型应用场景。开发者可利用此接口实现自动化操作,提升电商运营效率,降低人工成本。文中还总结了频率限制、数据缓存等避坑指南,助力开发者高效使用API。
|
8天前
|
机器学习/深度学习 JSON 算法
淘宝拍立淘按图搜索API接口系列的应用与数据解析
淘宝拍立淘按图搜索API接口是阿里巴巴旗下淘宝平台提供的一项基于图像识别技术的创新服务。以下是对该接口系列的应用与数据解析的详细分析
|
16天前
|
数据采集 供应链 API
实战指南:通过1688开放平台API获取商品详情数据(附Python代码及避坑指南)
1688作为国内最大的B2B供应链平台,其API为企业提供合法合规的JSON数据源,直接获取批发价、SKU库存等核心数据。相比爬虫方案,官方API避免了反爬严格、数据缺失和法律风险等问题。企业接入1688商品API需完成资质认证、创建应用、签名机制解析及调用接口四步。应用场景包括智能采购系统、供应商评估模型和跨境选品分析。提供高频问题解决方案及安全合规实践,确保数据安全与合法使用。立即访问1688开放平台,解锁B2B数据宝藏!
|
1天前
|
存储 前端开发 安全
如何在自己的网站接入API接口获取数据?分步指南与实战示例
将第三方API(如微店API)接入网站是扩展功能和获取实时数据的关键。流程包括注册开发者账号、申请API权限、设置认证机制(OAuth 2.0或AppKey签名)、调用API实现前后端协作、处理数据与错误、优化安全性能,并解决常见问题。确保遵循最佳实践,保障系统稳定与安全。通过这些步骤,开发者可高效整合数据,提升应用功能。
|
2天前
|
数据采集 消息中间件 API
微店API开发全攻略:解锁电商数据与业务自动化的核心能力
微店开放平台提供覆盖商品、订单、用户、营销、物流五大核心模块的API接口,支持企业快速构建电商中台系统。其API体系具备模块化设计、双重认证机制、高并发支持和数据隔离等特性。文档详细解析了商品管理、订单处理、营销工具等核心接口功能,并提供实战代码示例。同时,介绍了企业级整合方案设计,如订单全链路自动化和商品数据中台架构,以及性能优化与稳定性保障措施。最后,针对高频问题提供了排查指南,帮助开发者高效利用API实现电商数智化转型。适合中高级开发者阅读。
|
7天前
|
存储 缓存 监控
如何高效爬取天猫商品数据?官方API与非官方接口全解析
本文介绍两种天猫商品数据爬取方案:官方API和非官方接口。官方API合法合规,适合企业长期使用,需申请企业资质;非官方接口适合快速验证需求,但需应对反爬机制。详细内容涵盖开发步骤、Python实现示例、反爬策略、数据解析与存储、注意事项及扩展应用场景。推荐工具链包括Playwright、aiohttp、lxml等。如需进一步帮助,请联系作者。
|
8天前
|
JSON API 数据格式
淘宝商品评论API接口系列的应用与数据解析
在电商平台中,用户评论是了解商品质量、服务水平和用户满意度的重要数据来源。淘宝作为中国最大的电商平台,提供了商品评论API接口,帮助开发者获取和分析用户评价数据。本文将介绍淘宝商品评论API接口系列的作用、使用方法,并通过示例展示如何调用API并解析返回的JSON数据。
|
15天前
|
JSON JavaScript 前端开发
处理从API返回的JSON数据时返回Unicode编码字符串怎么处理
在处理API返回的JSON数据时,遇到类似`\u7f51\u7edc\u8fde\u63a5\u9519\u8bef`的Unicode编码字符串,可使用JavaScript内置方法转换为可读文字。主要方法包括:1. 使用`JSON.parse`自动解析;2. 使用`decodeURIComponent`和`escape`组合解码;3. 在API调用中直接处理响应数据。这些方法能有效处理多语言内容,确保正确显示非ASCII字符。
|
15天前
|
缓存 小程序 API
微信小程序网络请求与API调用:实现数据交互
本文深入探讨了微信小程序的网络请求与API调用,涵盖`wx.request`的基本用法、常见场景(如获取数据、提交表单、上传和下载文件)及注意事项(如域名配置、HTTPS协议、超时设置和并发限制)。通过一个简单案例,演示了如何实现小程序与服务器的数据交互。掌握这些技能将帮助你构建功能更丰富的应用。

热门文章

最新文章