Gemini REST API:构建你的加密货币交易机器人

2025-03-03 11:10:51 88

使用 Gemini REST API 构建你的加密货币交易机器人

Gemini 交易所提供了一个强大的 REST API,允许开发者构建自动化交易机器人、数据分析工具和其他与加密货币交易相关的应用程序。本文将深入探讨如何使用 Gemini REST API 进行身份验证、获取市场数据和执行交易,并提供一些代码示例,帮助你开始构建自己的加密货币交易机器人。

1. 身份验证与 API 密钥

在使用 Gemini REST API 之前,严格的身份验证流程是至关重要的。你需要先注册并创建一个 Gemini 账户,这是访问其交易平台和各种功能的先决条件。账户创建完成后,下一步便是生成 API 密钥对,这组密钥将作为你应用程序与 Gemini API 交互的凭证。

API 密钥由两部分组成:一个公共密钥(Public Key)和一个私有密钥(Private Key)。公共密钥的作用是唯一标识你的应用程序,类似于用户名,允许 Gemini 服务器识别请求的来源。更重要的是,私有密钥用于对所有发往 Gemini API 的请求进行数字签名。这个签名过程利用加密算法,确保请求的完整性和真实性,防止中间人攻击和数据篡改。换句话说,私有密钥的保密性至关重要,务必妥善保管,切勿泄露给任何第三方。

创建 API 密钥时,Gemini 允许你设置不同的权限,例如交易权限、提款权限或只读权限。根据你的应用程序的需求,仔细配置这些权限,遵循最小权限原则,只授予必要的访问权限,以降低潜在的安全风险。定期轮换 API 密钥也是一种良好的安全实践,可以进一步提高账户的安全性。

注意: 务必妥善保管你的私有密钥,不要将其泄露给他人。

Gemini REST API 使用 HTTP 签名进行身份验证。每个请求都必须包含一个 X-GEMINI-APIKEY 头,其中包含你的公共密钥,以及一个 X-GEMINI-PAYLOAD 头,其中包含请求数据的 JSON 编码的 Base64 编码的字符串。此外,还需要一个 X-GEMINI-SIGNATURE 头,其中包含使用你的私有密钥对 X-GEMINI-PAYLOAD 头部的值进行 HMAC-SHA384 加密后的字符串。

以下是一个 Python 函数,用于生成 Gemini API 请求的头部:

import base64 import hashlib import hmac import import time

def generateheaders(apikey, secretkey, requestpath, payload=None): """ 生成 Gemini API 请求头部。

Args: apikey: 你的 Gemini API 公共密钥。 secretkey: 你的 Gemini API 私有密钥。 request_path: API 请求的路径。 payload: 请求体数据,可选。

Returns: 一个包含所有必需的 Gemini API 头部信息的字典。 """

t = time.time() nonce = str(int(t * 1000))

if payload is None: payload = {}

payload['request'] = request_path payload['nonce'] = nonce

payload_ = .dumps(payload) payloadbase64 = base64.b64encode(payload.encode('utf-8'))

signature = hmac.new(secretkey.encode('utf-8'), payloadbase64, hashlib.sha384).hexdigest()

headers = { 'Content-Type': 'application/', 'X-GEMINI-APIKEY': apikey, 'X-GEMINI-PAYLOAD': payloadbase64.decode('utf-8'), 'X-GEMINI-SIGNATURE': signature }

return headers

2. 获取市场数据

Gemini REST API 提供了一系列强大的接口,允许开发者和交易者高效地访问和分析市场数据。通过这些接口,可以获取关键的市场信息,例如交易对的详细信息、实时的订单簿数据、最近发生的交易数据以及全面的历史交易数据,从而做出明智的交易决策。

具体来说,获取交易对信息接口可以提供每个交易对的最小交易单位、价格精度等重要参数,帮助用户更好地理解交易规则。订单簿数据接口能够实时反映市场的买卖盘情况,揭示市场的供需关系和潜在的价格变动方向。最新交易数据接口提供最近成交的价格、数量和时间戳,让用户及时掌握市场动态。历史交易数据接口则提供过去一段时间内的所有交易记录,可用于技术分析和回测交易策略。

获取交易对信息:

可以使用 /v1/symbols 端点获取 Gemini 交易所上所有可交易的交易对信息。此端点提供实时更新的数据,包括交易对的符号、价格、交易量等关键信息。通过调用此端点,开发者可以构建应用程序,监控市场动态,并执行自动化交易策略。

以下 Python 代码演示了如何使用 requests 库从 Gemini API 获取交易对信息:

import requests

def get_symbols():
  """
  获取 Gemini 交易所上所有可交易的交易对信息。

  Returns:
      一个包含所有交易对信息的列表。每个元素都是一个字符串,代表一个交易对的符号。
  """
  url = 'https://api.gemini.com/v1/symbols'
  try:
    response = requests.get(url)
    response.raise_for_status()   # 如果请求失败 (例如,HTTP 错误码 404, 500),则抛出异常
    return response.()
  except requests.exceptions.RequestException as e:
    print(f"请求失败: {e}")
    return None

symbols = get_symbols()
if symbols:
  print(symbols)

代码解释:

  • 导入 requests 库,用于发送 HTTP 请求。
  • 定义 get_symbols() 函数,用于封装 API 调用。
  • 指定 API 端点 URL 为 https://api.gemini.com/v1/symbols
  • 使用 requests.get(url) 发送 GET 请求,获取交易对信息。
  • 使用 response.raise_for_status() 检查响应状态码。如果状态码表示错误(例如 404 Not Found 或 500 Internal Server Error),则会引发一个 HTTPError 异常,从而允许程序捕获和处理错误。
  • 如果请求成功,则使用 response.() 将 JSON 响应数据解析为 Python 列表。
  • 打印包含所有交易对信息的列表。代码中加入了try...except语句处理可能发生的requests异常,使得程序更加健壮。
  • 代码执行后,会输出一个列表,其中包含了所有 Gemini 交易所支持的交易对,例如 ['BTCUSD', 'ETHUSD', 'LTCUSD', ...]。每个字符串代表一个交易对,例如 'BTCUSD' 表示比特币兑美元。

请注意,此代码需要安装 requests 库。可以使用以下命令安装:

pip install requests

获取订单簿数据:

可以使用 /v1/book/:symbol 端点获取指定交易对的订单簿数据。该端点提供市场深度信息,包括买单( bids )和卖单( asks )的价格和数量。 订单簿数据是实时更新的,反映了市场上最新的交易意愿。

以下是一个 Python 函数示例,展示如何使用 requests 库获取指定交易对的订单簿数据:


def get_order_book(symbol):
    """
    获取指定交易对的订单簿数据。

    Args:
        symbol: 交易对的符号,例如 'btcusd'。常见的交易对包括 'btcusd'(比特币/美元),'ethusd'(以太坊/美元)等。 请务必使用交易所支持的正确交易对符号。

    Returns:
        一个包含订单簿数据的字典。返回的字典通常包含 'bids'(买单)和 'asks'(卖单)两个键,每个键对应一个列表,列表中的每个元素代表一个订单,包含价格和数量信息。
    """
    url = f'https://api.gemini.com/v1/book/{symbol}'
    try:
        response = requests.get(url)
        response.raise_for_status()  # 如果响应状态码不是 200,则抛出 HTTPError 异常
        return response.()
    except requests.exceptions.RequestException as e:
        print(f"请求出错:{e}")
        return None # 或者抛出异常,具体取决于你的错误处理策略

代码解释:

  • def get_order_book(symbol): 定义了一个名为 get_order_book 的函数,该函数接受一个参数 symbol ,表示要查询的交易对。
  • url = f'https://api.gemini.com/v1/book/{symbol}' 构建 API 请求的 URL。 f-string 用于将交易对符号插入到 URL 中。
  • response = requests.get(url) 使用 requests 库发送 GET 请求到指定的 URL。
  • response.raise_for_status() 检查响应状态码。 如果状态码指示错误(例如 404 或 500),则会引发 HTTPError 异常。
  • return response.() 将响应内容解析为 JSON 格式的 Python 字典并返回。
  • except requests.exceptions.RequestException as e: 使用 try...except 块来捕获可能发生的请求异常(例如网络连接错误)。
  • print(f"请求出错:{e}") 打印错误信息,方便调试。 在生产环境中,应该使用更完善的日志记录机制。
  • return None 如果发生错误,返回 None 。 也可以选择抛出异常,具体取决于你的错误处理策略。

以下是如何使用该函数的示例:


order_book = get_order_book('btcusd')
if order_book:
    print(order_book)
else:
    print("获取订单簿数据失败。")

这段代码调用 get_order_book 函数来获取 'btcusd' 交易对的订单簿数据,然后打印结果。请注意,实际的 API 地址和数据格式可能因交易所而异。 在使用此代码之前,请务必参考交易所的 API 文档。

获取最新交易数据:

可以使用 /v1/trades/:symbol 端点从 Gemini 交易所获取指定交易对的最新交易数据。该接口允许开发者实时跟踪市场动态,分析交易趋势。

以下 Python 代码示例演示了如何使用 requests 库调用 Gemini API 获取交易数据:


import requests
import 

def get_trades(symbol):
    """
    获取指定交易对的最新交易数据。

    Args:
        symbol: 交易对的符号,例如 'btcusd'。

    Returns:
        一个包含最新交易数据的 JSON 列表,每个元素代表一笔交易。
        如果请求失败,会抛出 HTTPError 异常。
    """
    url = f'https://api.gemini.com/v1/trades/{symbol}'
    try:
        response = requests.get(url)
        response.raise_for_status()  # 检查响应状态码,如果不是 200 则抛出 HTTPError
        return response.()
    except requests.exceptions.HTTPError as e:
        print(f"HTTPError: {e}")
        return None
    except requests.exceptions.RequestException as e:
        print(f"RequestException: {e}")
        return None

trades = get_trades('btcusd')

if trades:
    print(.dumps(trades, indent=4))  # 使用 .dumps 格式化输出,方便阅读
else:
    print("获取交易数据失败")

代码详解:

  • import requests 导入 requests 库,用于发送 HTTP 请求。
  • import 导入 库,用于处理 JSON 数据。
  • get_trades(symbol) 函数接收一个交易对符号 symbol 作为参数。
  • url = f'https://api.gemini.com/v1/trades/{symbol}' 构造 API 请求 URL,使用 f-string 格式化字符串。
  • response = requests.get(url) 发送 GET 请求到 API 端点。
  • response.raise_for_status() 检查响应状态码。如果状态码表示错误 (例如 404, 500),则会抛出一个 HTTPError 异常。这是一种良好的实践,可以确保程序能够正确处理 API 错误。
  • return response.() 将响应内容解析为 JSON 格式的 Python 列表。
  • 添加了更详细的异常处理,包括 HTTPError RequestException ,使得代码更加健壮。 RequestException 是一个更通用的异常,可以捕获网络连接错误等问题。
  • 使用 .dumps(trades, indent=4) 格式化输出 JSON 数据,增加了可读性。 indent=4 表示使用 4 个空格进行缩进。
  • 添加了错误处理,如果 get_trades 函数返回 None ,则打印 "获取交易数据失败"。

API 响应数据结构示例 (JSON):


[
    {
        "price": "30000.00",
        "amount": "0.01",
        "timestamp": 1678886400,
        "timestampms": 1678886400000,
        "tid": 123456789,
        "type": "buy",
        "aggressor": false
    },
    {
        "price": "30001.00",
        "amount": "0.02",
        "timestamp": 1678886401,
        "timestampms": 1678886401000,
        "tid": 123456790,
        "type": "sell",
        "aggressor": true
    }
]

字段说明:

  • price : 交易价格。
  • amount : 交易数量。
  • timestamp : Unix 时间戳 (秒)。
  • timestampms : Unix 时间戳 (毫秒)。
  • tid : 交易 ID。
  • type : 交易类型, buy 表示买入, sell 表示卖出。
  • aggressor : 指示这笔交易是否是主动成交方发起的。 true 表示主动成交方, false 表示被动成交方。

3. 执行交易

Gemini REST API 提供了一套完整的接口,允许你方便地提交、取消和查询订单,从而实现全面的交易管理。通过API,你可以创建各种类型的订单,例如限价单(Limit Order)、市价单(Market Order)和止损单(Stop Order),以满足不同的交易策略需求。提交订单时,你需要指定交易对(例如BTCUSD)、订单类型、数量和价格(如果适用)。

取消订单同样至关重要。Gemini REST API 允许你通过订单ID精确地取消特定订单。及时取消未成交的订单可以帮助你调整策略,避免不必要的风险。

查询订单状态是有效管理交易的关键环节。API 提供了查询订单状态的接口,允许你实时了解订单的执行情况,包括订单是否已成交、部分成交或已被取消。这有助于你监控交易进度,及时做出反应。

利用 Gemini REST API 进行交易时,务必注意安全性和风险管理。仔细阅读 Gemini API 文档,了解所有参数的含义和潜在风险。采取必要的安全措施,例如使用 API 密钥进行身份验证,并设置适当的权限,以确保账户安全。

提交新订单:

可以使用 /v1/order/new 端点提交新订单到Gemini交易所。为了成功提交订单,您需要提供一系列关键参数,包括:指定交易对的符号(例如 'btcusd' 或 'ethbtc'),希望交易的数量,期望的成交价格,订单类型(例如 'limit' 表示限价单)以及交易方向,即 'buy'(买入)或 'sell'(卖出)。请务必确保提供的参数符合Gemini交易所的规范,以避免订单提交失败。

以下Python代码示例展示了如何使用Gemini API提交新订单:


def new_order(api_key, secret_key, symbol, amount, price, side):
  """
  提交新订单到Gemini交易所。

  Args:
    api_key:  你的 Gemini API 公共密钥,用于身份验证。
    secret_key: 你的 Gemini API 私有密钥,用于生成签名,确保请求的安全性。
    symbol:  交易对的符号,例如 'btcusd' 表示比特币兑美元。
    amount: 订单的数量,表示希望交易的加密货币数量。
    price: 订单的价格,表示期望的成交价格。
    side: 买卖方向,'buy' 表示买入,'sell' 表示卖出。

  Returns:
    一个包含订单信息的字典,其中包含订单ID、状态、成交价格等详细信息。
  """

  url = 'https://api.gemini.com/v1/order/new'

  payload = {
    'client_order_id': 'your_client_order_id',  # 替换为您自己的唯一客户端订单ID,便于跟踪订单状态
    'symbol': symbol,
    'amount': str(amount), # 必须将数量转换为字符串
    'price': str(price), # 必须将价格转换为字符串
    'side': side,
    'type': 'exchange limit', # "exchange limit" 是Gemini交易所指定的限价单类型名称
    'options': ["maker-or-cancel"]   # "maker-or-cancel" 选项表示仅在订单能够成为maker (挂单) 的情况下才执行,否则取消订单。这有助于降低交易费用。还可以考虑使用 "immediate-or-cancel" (IOC) 或 "fill-or-kill" (FOK) 等其他选项。
  }

  headers = generate_headers(api_key, secret_key, '/v1/order/new', payload)

  response = requests.post(url, headers=headers, =payload) #将 payload 序列化为JSON格式
  response.raise_for_status() # 检查HTTP状态码,如果不是200,则抛出异常
  return response.() #将响应数据解析为JSON格式的字典

请务必注意,在实际使用中,需要替换代码中的 your_client_order_id 为您自己的唯一客户端订单ID。需要根据实际情况调整 amount price 的值,并根据您的需求选择合适的 options generate_headers 函数负责生成包含API密钥和签名的HTTP头部,以确保请求的安全性。

Example usage (replace with your actual API keys and order details):

apikey = 'YOURAPI_KEY'

secretkey = 'YOURSECRET_KEY'

orderresult = neworder(apikey, secretkey, 'btcusd', 0.001, 30000, 'buy')

print(order_result)

取消订单

可以使用 /v1/order/cancel API 端点来取消一个挂单。成功调用此端点需要提供您希望取消订单的唯一标识符,即订单ID。务必仔细核对订单ID,确保取消正确的订单。

以下Python代码示例展示了如何通过Gemini API取消指定ID的订单:


def cancel_order(api_key, secret_key, order_id):
  """
  取消指定ID的订单。

  Args:
    api_key: 您的 Gemini API 公共密钥。请妥善保管,避免泄露。
    secret_key: 您的 Gemini API 私有密钥。切勿分享给他人。
    order_id: 需要取消的订单的唯一ID。必须是有效的订单ID。

  Returns:
    一个包含取消订单信息的字典。如果取消成功,将包含订单的状态信息。
    如果取消失败,将抛出异常。
  """

  url = 'https://api.gemini.com/v1/order/cancel'

  payload = {
    'order_id': order_id
  }

  headers = generate_headers(api_key, secret_key, '/v1/order/cancel', payload)

  response = requests.post(url, headers=headers, =payload)  # 使用参数发送payload
  response.raise_for_status()  # 检查HTTP状态码,如果不是200则抛出异常
  return response.() # 将响应体解析为JSON格式

代码解释:

  • api_key secret_key 分别代表您的 Gemini API 公共密钥和私有密钥。这些密钥用于对API请求进行身份验证,确保您的操作被授权。请妥善保管您的私钥,避免泄露。
  • order_id 是您要取消的订单的唯一标识符。您可以通过查询您的订单历史记录或未成交订单列表来获取此ID。
  • generate_headers 函数(代码中未显示)负责生成带有正确签名的HTTP请求头。该签名基于您的API密钥、私钥、请求路径和请求负载计算得出,用于验证请求的完整性和真实性。
  • 使用 requests.post 方法发送POST请求到 /v1/order/cancel 端点,并将订单ID作为请求负载发送。请注意将 payload 通过 =payload 传递给 requests.post ,确保以JSON格式发送。
  • response.raise_for_status() 用于检查HTTP响应状态码。 如果状态码指示错误(例如400、404、500),此方法将抛出一个 HTTPError 异常,停止程序执行。
  • response.() 将响应内容解析为JSON格式的字典,其中包含有关取消订单的信息。

错误处理:

在实际应用中,务必包含适当的错误处理机制,以应对API请求失败的情况。例如,您可以捕获 requests.exceptions.RequestException 异常来处理网络连接问题,或者捕获API返回的特定错误代码来处理订单不存在、权限不足等错误。

注意事项:

  • 取消订单并非总是立即生效。在某些情况下,订单可能已经在处理中,无法取消。
  • 取消订单可能会产生费用,具体取决于您的交易类型和 Gemini 的费用政策。
  • 在取消订单之前,请仔细检查订单信息,确保您要取消的是正确的订单。
  • 建议在取消订单后,立即查询您的订单历史记录或未成交订单列表,以确认订单是否已成功取消。

Example usage (replace with your actual API keys and order ID):

apikey = 'YOURAPI_KEY'

secretkey = 'YOURSECRET_KEY'

cancelresult = cancelorder(apikey, secretkey, 12345) # Replace 12345 with the actual order ID

print(cancel_result)

查询订单状态:

您可以使用 /v1/order/status API 端点来查询特定订单的当前状态。查询时必须提供相应的订单 ID。 此端点允许开发者实时跟踪订单的执行情况,从而更好地管理交易策略和风险。

以下 Python 代码片段展示了如何通过 Gemini API 查询订单状态。 请确保您已安装 requests 库: pip install requests .


def get_order_status(api_key, secret_key, order_id):
  """
  查询订单的状态。

  Args:
    api_key: 您的 Gemini API 公共密钥。
    secret_key: 您的 Gemini API 私有密钥。
    order_id: 要查询的订单的 ID。

  Returns:
    一个包含订单状态信息的字典。  如果发生错误,则返回 None。
  """
  import requests
  import hashlib
  import hmac
  import 
  import base64

  url = 'https://api.gemini.com/v1/order/status'

  payload = {
    'order_id': order_id,
    'nonce': str(int(round(time.time() * 1000))) # 添加 nonce 字段,防止重放攻击
  }
  encoded_payload = .dumps(payload).encode()
  b64 = base64.b64encode(encoded_payload)
  signature = hmac.new(secret_key.encode(), b64, hashlib.sha384).hexdigest()

  headers = {
      'Content-Type': 'application/',
      'X-GEMINI-APIKEY': api_key,
      'X-GEMINI-PAYLOAD': b64,
      'X-GEMINI-SIGNATURE': signature
  }

  try:
    response = requests.post(url, headers=headers, data=encoded_payload) # 使用 data 传递 payload
    response.raise_for_status() # 抛出 HTTPError 异常 (4XX, 5XX)
    return response.()
  except requests.exceptions.RequestException as e:
    print(f"API 请求失败: {e}")
    return None # 发生异常时返回 None

get_order_status 函数接收三个参数:您的 Gemini API 公共密钥 ( api_key ),您的 Gemini API 私有密钥 ( secret_key ),以及您要查询的订单的 ID ( order_id )。

此函数构造一个包含 order_id nonce 的 JSON payload。 nonce 是一个单调递增的数字,用于防止重放攻击。 然后,使用您的私有密钥对 payload 进行签名,并将其作为 HTTP header 发送。

请求成功后,函数将返回一个包含订单状态信息的 JSON 字典。该字典可能包含诸如订单创建时间、原始数量、剩余数量、平均执行价格、当前状态 (例如, open closed cancelled ) 等详细信息。 如果请求失败(例如,由于身份验证错误或无效的 order_id ),函数将抛出一个异常并返回 None

重要的是要正确处理 API 密钥,并将其存储在安全的位置,例如环境变量或密钥管理系统。 避免将密钥硬编码到您的应用程序中,以免泄露。

Example usage (replace with your actual API keys and order ID):

apikey = 'YOURAPI_KEY'

secretkey = 'YOURSECRET_KEY'

orderstatus = getorderstatus(apikey, secret_key, 12345) # Replace 12345 with the actual order ID

print(order_status)

4. 其他重要的 API 端点

Gemini REST API 除了交易和市场数据之外,还提供了一系列其他重要的 API 端点,用于账户管理、历史数据查询等操作。

  • /v1/balances : 此端点允许用户查询其在 Gemini 交易所的账户余额。返回的信息包括各种加密货币和法币的可用余额、已用余额以及总余额。用户可以利用此信息监控其资金状况,进行资产管理。该接口返回的数据会详细列出不同币种的余额情况,方便用户掌握账户资产分布。
  • /v1/mytrades : 通过此端点,用户可以获取其在 Gemini 交易所的完整交易历史记录。返回的数据包括交易时间、交易对、交易类型(买入或卖出)、交易价格、交易数量以及手续费等详细信息。利用这些信息,用户可以分析其交易策略,评估交易绩效,并进行税务申报。该接口支持按时间范围查询,方便用户检索特定时间段内的交易记录。
  • /v1/notionalvolume : 该端点用于查询用户在 Gemini 交易所的名义交易量。名义交易量是指用户在特定时间段内交易的总价值,通常以美元或其他法币计价。该信息对于参与 Gemini 的交易量等级计划或其他奖励计划非常重要。交易所会根据用户的交易量等级提供不同的手续费折扣或其他优惠。用户可以通过此接口了解自己的交易量等级,并优化交易策略以获取更多优惠。

5. 注意事项

  • 保持信息同步: 务必定期查阅 Gemini API 的官方文档,深入了解最新的 API 端点、参数规范、请求方式以及任何可能发生的变更。这将确保你的程序始终与 Gemini 平台保持兼容。
  • 错误处理机制: 在程序设计中,必须包含健全的错误处理逻辑。仔细分析 API 响应中可能出现的各种错误代码,并据此采取相应的补救措施,例如重试请求、记录错误日志或向用户发出警报,以避免程序因异常而崩溃。
  • 速率限制管理: Gemini API 对请求频率设有严格的限制。你需要根据自身的应用场景,合理设置请求间隔和并发数量,避免超出速率限制而被 Gemini 平台屏蔽。可以利用 API 返回的速率限制信息进行动态调整。
  • API 密钥安全: API 密钥是访问 Gemini API 的凭证,务必妥善保管。不要将密钥硬编码到程序中,更不要将其泄露到公共代码仓库或客户端应用程序中。推荐使用环境变量或配置文件来存储密钥,并采取必要的权限控制措施。
  • 沙盒环境测试: 在正式部署交易机器人之前,务必先在 Gemini 提供的沙盒环境中进行充分的测试。沙盒环境模拟了真实的交易场景,但使用虚拟资金,可以让你在不承担实际风险的情况下验证程序的正确性和稳定性。
  • 市场风险防范: 加密货币市场波动剧烈,交易存在高度风险。在设计交易机器人时,务必充分考虑市场风险,并制定完善的风险管理策略,例如设置止损点、分散投资、控制仓位大小等,以避免遭受重大损失。

本文旨在为你提供 Gemini REST API 使用的初步指导,助你踏上构建加密货币交易机器人的旅程。需要明确的是,本文仅仅是入门指南,加密货币交易涉及的知识和技术非常广泛,希望你能在实践中不断学习和探索,提升自身的专业水平。

The End

发布于:2025-03-03,除非注明,否则均为链探索原创文章,转载请注明出处。