• python获取新浪财经可转债行情数据


    """
    author:汉江S
    微博:汉江S
    """
    from urllib.request import urlopen  # python自带爬虫库
    import pandas as pd
    from datetime import datetime
    import time
    import re  # 正则表达式库
    import os  # 系统库
    import json  # python自带的json数据库
    pd.set_option('expand_frame_repr', False)  # 当列太多时不换行
    pd.set_option('display.max_rows', 5000)  # 最多显示数据的行数
    
    
    # =====函数:从网页上抓取数据
    def get_content_from_internet(url, max_try_num=10, sleep_time=5):
        """
        使用python自带的urlopen函数,从网页上抓取数据
        :param url: 要抓取数据的网址
        :param max_try_num: 最多尝试抓取次数
        :param sleep_time: 抓取失败后停顿的时间
        :return: 返回抓取到的网页内容
        """
        get_success = False  # 是否成功抓取到内容
        # 抓取内容
        for i in range(max_try_num):
            try:
                content = urlopen(url=url, timeout=10).read()  # 使用python自带的库,从网络上获取信息
                get_success = True  # 成功抓取到内容
                break
            except Exception as e:
                print('抓取数据报错,次数:', i+1, '报错内容:', e)
                time.sleep(sleep_time)
    
        # 判断是否成功抓取内容
        if get_success:
            return content
        else:
            raise ValueError('使用urlopen抓取网页数据不断报错,达到尝试上限,停止程序,请尽快检查问题所在')
    
    
    # =====函数:从新浪获取指定股票的数据
    def get_today_data_from_sinajs(code_list):
        """
        返回一串股票最近一个交易日的相关数据
        从这个网址获取股票数据:http://hq.sinajs.cn/list=sh600000,sz000002,sz300001
        正常网址:https://finance.sina.com.cn/realstock/company/sh600000/nc.shtml,
        :param code_list: 一串股票代码的list,可以多个,例如[sh600000, sz000002, sz300001],
        :return: 返回一个存储股票数据的DataFrame
        """
    
        # 构建url
        url = "http://hq.sinajs.cn/list=" + ",".join(code_list)
    
        # 抓取数据
        content = get_content_from_internet(url)
        content = content.decode('gbk')
    
        # 将数据转换成DataFrame
        content = content.strip()  # 去掉文本前后的空格、回车等
        data_line = content.split('
    ')  # 每行是一个股票的数据
        data_line = [i.replace('var hq_str_', '').split(',') for i in data_line]
        df = pd.DataFrame(data_line, dtype='float')  #
    
        # 对DataFrame进行整理
        df[0] = df[0].str.split('="')
        df['stock_code'] = df[0].str[0].str.strip()
        df['stock_name'] = df[0].str[-1].str.strip()
        df['candle_end_time'] = df[30] + ' ' + df[31]  # 股票市场的K线,是普遍以当跟K线结束时间来命名的
        df['candle_end_time'] = pd.to_datetime(df['candle_end_time'])
        rename_dict = {1: 'open', 2: 'pre_close', 3: 'close', 4: 'high', 5: 'low', 6: 'buy1', 7: 'sell1',
                       8: 'amount', 9: 'volume', 32: 'status'}  # 自己去对比数据,会有新的返现
        # 其中amount单位是股,volume单位是元
        df.rename(columns=rename_dict, inplace=True)
        df['status'] = df['status'].str.strip('";')
        df = df[['stock_code', 'stock_name', 'candle_end_time', 'open', 'high', 'low', 'close', 'pre_close', 'amount',
                 'volume', 'buy1', 'sell1', 'status']]
    
        return df
    
    # test = get_today_data_from_sinajs(code_list=['sh000001','sz399001'])
    # print(test)
    
    # =====函数:判断今天是否是交易日
    def is_today_trading_day():
        """
        判断今天是否是交易日
        :return: 如果是返回True,否则返回False
        """
    
        # 获取上证指数今天的数据
        df = get_today_data_from_sinajs(code_list=['sh000001','sz399001'])
        sh_date = df.iloc[0]['candle_end_time']  # 上证指数最近交易日
    
        # 判断今天日期和sh_date是否相同
        return datetime.now().date() == sh_date.date()
    # test3 = is_today_trading_day()
    # print(test3)
    
    # =====函数:从新浪获取所有股票的数据
    def get_all_today_stock_data_from_sina_marketcenter():
        """
        http://vip.stock.finance.sina.com.cn/mkt/#stock_hs_up
        从新浪网址的上述的网址,逐页获取最近一个交易日所有股票的数据
        :return: 返回一个存储股票数据的DataFrame
        """
    
        # ===数据网址
        headers = {
            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36",
        }
        #股票数据
        raw_url = 'http://vip.stock.finance.sina.com.cn/quotes_service/api/json_v2.php/Market_Center.getHQNodeData?page=%s' 
                  '&num=40&sort=symbol&asc=1&node=hs_a&symbol=&_s_r_a=sort'
        #可转债数据
        raw_url = 'http://vip.stock.finance.sina.com.cn/quotes_service/api/json_v2.php/Market_Center.getHQNodeDataSimple?page=%s&num=80&sort=symbol&asc=0&node=hskzz_z&_s_r_a=sort'
        page_num = 1
        # ===存储数据的DataFrame
        all_df = pd.DataFrame()
    
        # ===获取上证指数最近一个交易日的日期。此段代码在课程视频中没有,之后补上的
        df = get_today_data_from_sinajs(code_list=['sh000001','sz399001'])
        sh_date = df.iloc[0]['candle_end_time'].date()  # 上证指数最近交易日
    
        # ===开始逐页遍历,获取股票数据
        while True:
            # 构建url
            url = raw_url % (page_num)
            print('开始抓取页数:', page_num)
    
            # 抓取数据
            content = get_content_from_internet(url)
            content = content.decode('gbk')
    
    
            # 判断页数是否为空
            if '[]' in content:
                print('抓取到页数的尽头,退出循环')
                break
    
            # 通过正则表达式,给key加上引号
            content = re.sub(r'(?<={|,)([a-zA-Z][a-zA-Z0-9]*)(?=:)', r'"1"', content)
    
            # 将数据转换成dict格式
            content = json.loads(content)
    
            # 将数据转换成DataFrame格式
            df = pd.DataFrame(content, dtype='float')
            # 对数据进行整理
            # 重命名
            rename_dict = {'symbol': '股票代码', 'name': '股票名称', 'open': '开盘价', 'high': '最高价', 'low': '最低价',
                           'trade': '收盘价', 'settlement': '前收盘价', 'volume': '成交量', 'amount': '成交额'}
            df.rename(columns=rename_dict, inplace=True)
            # 添加交易日期
            df['交易日期'] = pd.to_datetime(sh_date)  # 在课程视频中使用的是上一行代码,现在改成本行代码,程序更加稳健
    
            # 取需要的列
            df = df[['股票代码', '股票名称', '交易日期', '开盘价', '最高价', '最低价', '收盘价', '前收盘价', '成交量', '成交额']]
    
            # 合并数据
            all_df = all_df.append(df, ignore_index=True)
    
            # 将页数+1
            page_num += 1
            time.sleep(1)
    
        # ===将当天停盘的股票删除,此段代码在课程视频中没有,之后补上的
        all_df = all_df[all_df['开盘价'] - 0 > 0.00001]
        all_df.reset_index(drop=True, inplace=True)
    
        # ===返回结果
        return all_df
    
    # test = get_all_today_stock_data_from_sina_marketcenter()
    # print(test)
    
    # 判断今天是否是交易日
    if is_today_trading_day() is False:
        print('今天不是交易日,不需要更新股票数据,退出程序')
        exit()
    
    # 判断当前时间是否超过15点
    if datetime.now().hour < 15:  # 保险起见可以小于16点
        print('今天股票尚未收盘,不更新股票数据,退出程序')
        exit()
    
    
    # 获取今天所有的股票数据
    df = get_all_today_stock_data_from_sina_marketcenter()
    
    # 对数据进行存储
    for i in df.index:
        t = df.iloc[i:i+1, :]
        stock_code = t.iloc[0]['股票代码']
    
        # 构建存储文件路径
        path = '../data/'+ stock_code + '.csv'
        # 文件存在,不是新股
        if os.path.exists(path):
            t.to_csv(path, header=None, index=False, mode='a', encoding='gbk')
        # 文件不存在,说明是新股
        else:
            # 先将头文件输出
            t.to_csv(path, index=False, mode='a', encoding='gbk')
        print(stock_code)
  • 相关阅读:
    VMware安装CentOS系统与配置全过程
    Matplotlib学习笔记
    python正则表达式字符记录
    HyperLedger Fabric 学习思路分享
    fabric-sdk-container v1.0-beta 新增支持多服务节点
    HyperLedger/Fabric SDK使用Docker容器镜像快速部署上线
    HyperLedger/Fabric JAVA-SDK with 1.1
    HyperLedger Fabric 1.1 手动部署单机单节点
    Hyperledger Fabric CA User’s Guide——配置设置(四)
    Hyperledger Fabric CA User’s Guide——开始(三)
  • 原文地址:https://www.cnblogs.com/hanjiangs/p/14310597.html
Copyright © 2020-2023  润新知