昨天在看 Github 的时候,看到作者使用了 coinmarketcap 的 API ,昨天我去看了下 这个 API ,还是挺好用的,有文档,免费的,正好结合 requests 和 python 线程池,来 做个是示例。

API 文档 请戳这里

API 返回示例:

coin market cap api result

抓取代码如下:

# -*- coding: utf-8 -*-

"""

    This script try to use multiprocess to crawl coin real time coin
    price from CoinMarketCap.

    Created: 2018/3/8
    Copyright: (c) 2018<smileboywtu@gmail.com>

"""

import time
from argparse import ArgumentParser
from concurrent.futures import ThreadPoolExecutor
from concurrent.futures import as_completed

import requests

Usage = '''
python3 main.py [options] coin[,coin...]

Example:
python main.py cybermiles,gifto,bitcoin
'''

Description = '''
Crawl Coin price from CoinMarketCap
'''


def parse_args():
    """
    Add arguments to script

    :return:
    """
    parser = ArgumentParser(usage=Usage, description=Description)
    parser.add_argument(
        '-p', "--period",
        default=5,
        type=int,
        help="refresh data period"
    )
    parser.add_argument(
        "coin",
        type=str,
        default="BTC",
        help="monitor coin price, multiple coin separated by ,"
    )
    return parser.parse_args()


def crawl_price(coin: str, convert: str = "CNY") -> dict:
    """
    Use request to crawl coin price
    Use CNY(RMB) as default concurrency

    :param coin:
    :param convert:
    :return:
    """
    base_url = "https://api.coinmarketcap.com/v1/ticker/{0}/".format(coin)
    params = {
        "convert": convert
    }
    resp = requests.get(base_url, params=params, timeout=3)
    if resp.status_code // 100 not in (2, 3):
        return {}

    return resp.json()[0]


def main():
    """
    main function

    :return:
    """
    args = parse_args()
    coins = args.coin.split(",")
    results = []

    def job():
        with ThreadPoolExecutor(10) as executor:
            futures = {
                coin: executor.submit(crawl_price, coin)
                for coin in coins
            }

            for future in as_completed(futures.values()):
                result = future.result()
                if not result:
                    continue
                results.append(future.result())

    while True:
        results = []
        job()
        print(results)
        time.sleep(args.period)


if __name__ == "__main__":
    main()

标准输出:

usage:
python3 main.py [options] coin[,coin...]

Example:
python main.py cybermiles,gifto,bitcoin

Crawl Coin price from CoinMarketCap

positional arguments:
  coin                  monitor coin price, multiple coin separated by ,

optional arguments:
  -h, --help            show this help message and exit
  -p PERIOD, --period PERIOD
                        refresh data period

程序输出:

(coineye) ➜  CoinEye python main.py cybermiles,gifto,bitcoin
[{'id': 'bitcoin', 'name': 'Bitcoin', 'symbol': 'BTC', 'rank': '1', 'price_usd': '9736.89', 'price_btc': '1.0', '24h_volume_usd': '8929930000.0', 'market_cap_usd': '164616243940', 'available_supply': '16906450.0', 'total_supply': '16906450.0', 'max_supply': '21000000.0', 'percent_change_1h': '-0.34', 'percent_change_24h': '-10.08', 'percent_change_7d': '-7.25', 'last_updated': '1520479466', 'price_cny': '61602.7811755', '24h_volume_cny': '56497354258.1', 'market_cap_cny': '1041484339804'}, {'id': 'cybermiles', 'name': 'CyberMiles', 'symbol': 'CMT', 'rank': '201', 'price_usd': '0.107349', 'price_btc': '0.00001111', '24h_volume_usd': '10196900.0', 'market_cap_usd': '47791534.0', 'available_supply': '445197759.0', 'total_supply': '1000000000.0', 'max_supply': None, 'percent_change_1h': '-1.01', 'percent_change_24h': '-22.04', 'percent_change_7d': '-22.75', 'last_updated': '1520479456', 'price_cny': '0.6791693196', '24h_volume_cny': '64513145.3029', 'market_cap_cny': '302364659.0'}, {'id': 'gifto', 'name': 'Gifto', 'symbol': 'GTO', 'rank': '211', 'price_usd': '0.28143', 'price_btc': '0.00002914', '24h_volume_usd': '4982830.0', 'market_cap_usd': '44426913.0', 'available_supply': '157861327.0', 'total_supply': '1000000000.0', 'max_supply': None, 'percent_change_1h': '-0.34', 'percent_change_24h': '-16.2', 'percent_change_7d': '-28.79', 'last_updated': '1520479457', 'price_cny': '1.7805347196', '24h_volume_cny': '31525074.857', 'market_cap_cny': '281077573.0'}]

本篇主要是让大家熟悉 requests 的使用,以及 python3 的线程池。