def data2stockReport(datas): '''将 json形式的数据 转换成 list,list内元素是 stock_report类对象 :param data: :return: ''' reports = [] if datas is None: return reports for data in datas: utils.myprint(2, 'data2stockReport, report: ' + str(data)) # { 个股研报的格式,来自响应内容的 "Data": Array[10] # 'Title': '疫情导致业绩短期承压,5G放量依旧可期', # 'PUBLISHDATE': '2020-08-27 00:00:00', # 'Url': 'http://data.eastmoney.com/report/zw_stock.jshtml?encodeUrl=BmiolVIlr6KZkgoJQ09hBe8NSWD5/MhonF1FM3bjndI=', # 'StockName': '<em>中新赛克</em>', # 'INFOBODYCONTENT': ''} reports.append( report.stock_report(data['Title'], data['PUBLISHDATE'], data['Url'], re.sub(r'[</em><em>]', '', data['StockName']), data['INFOBODYCONTENT'])) return reports
def query_stock_by_group(self, **kwargs): '''根据分组条件条件来帅选股票代码,条件有group1, group2, group3, group4等 :param kwargs: (group1, group2, group3, group4, 四选一)字段 :return: [(code1, name1), (code2, name2), ...] ''' utils.myprint(2, 'query_stock_by_condition, param: ' + str(kwargs)) conn = sqlite3.connect(self.db) cursor = conn.cursor() sql = 'select code, name from %s where ' % (self.table_followed_stocks) if len(kwargs) < 1: sql = 'select code, name from %s ' % (self.table_followed_stocks) elif 'a_h' in kwargs: sql += 'a_h = %d' % (kwargs['a_h']) elif 'group1' in kwargs: # 马教授 sql += 'group1 = %d' % (kwargs['group1']) elif 'group2' in kwargs: # 科技类 sql += 'group2 = %d' % (kwargs['group2']) elif 'group3' in kwargs: # 消费量 sql += 'group3 = %d' % (kwargs['group3']) elif 'group4' in kwargs: # 刘备教授 sql += 'group4 = %d' % (kwargs['group4']) utils.myprint(1, 'query_stock_by_condition, sql: ' + sql) cursor.execute(sql) sql_result = cursor.fetchall() cursor.close() conn.close() return sql_result
def dict2marketData(data): '''提取关键的行情数据 :param data: :return: ''' if data is None: utils.myprint(3, 'dict2marketData, data is None') return return marketdata.marketData( data['f57'], # 股票代码 data['f58'], # 股票名字 data['f43'], # 最新 data['f46'], # 今开 data['f60'], # 昨收 data['f71'], # 均价 data['f44'], # 最高 data['f45'], # 最低 data['f51'], # 涨停价 data['f52'], # 跌停价 data['f47'], # 成交量 data['f48'], # 成交额 data['f135'], # 主力流入 data['f136'], # 主力流出 data['f117'], # 流通市值 data['f116'], # 总市值 data['f122'] # 今年以来涨跌幅 )
def create_table_followed_stocks(self, table_name): if type(table_name) != str or len(table_name.strip()) < 1: info = 'create_table_followed_stocks, param[table_name: %s] invalid' % ( str(table_name)) raise Exception(info) utils.myprint( 2, 'create_table_followed_stocks, db: ' + self.db + ', table_name: ' + table_name) conn = sqlite3.connect(self.db) cursor = conn.cursor() cursor.execute('CREATE TABLE IF NOT EXISTS %s (' 'id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, ' 'code VARCHAR(20) NOT NULL DEFAULT \'999999\', ' 'name VARCHAR(20), ' 'a_h BOOLEAN, ' 'group1 BOOLEAN, ' 'group2 BOOLEAN, ' 'group3 BOOLEAN, ' 'group4 BOOLEAN, ' 'date TEXT)' % (table_name)) cursor.close() conn.close()
def insert_followedStock(self, data): conn = sqlite3.connect(self.db) cursor = conn.cursor() sql = 'insert into %s (code, name, a_h, group1, group2, group3, group4, date) values (\'%s\', \'%s\', %d, %d, %d, %d, %d, \'%s\')' % ( self.table_followed_stocks, data['code'], data['name'], data['a_h'], data['group1'], data['group2'], data['group3'], data['group4'], data['date']) utils.myprint(2, 'insert_followedStock, insert sql: ' + str(sql)) cursor.execute(sql) cursor.close() conn.commit() conn.close()
def query_allstock(self): '''查询所以已关注的股票代码,除开港股的 :return: [(code1, name1), (code2, name2), ...] ''' conn = sqlite3.connect(self.db) cursor = conn.cursor() sql = 'select code, name from %s where a_h=1' % ( self.table_followed_stocks) utils.myprint(1, 'query_allcode, sql: ' + sql) cursor.execute(sql) sql_result = cursor.fetchall() cursor.close() conn.close() return sql_result
def insert_marketData(self, data): '''插入指定股票的当日行情数据,该行情数据是在当日股市收盘后从东方财富网址爬取的。 :param marketData: 行情数据 :return: ''' if data is None and not isinstance(data, marketdata.marketData): utils.myprint(3, 'insert_marketData, 参数不合法, marketData: ' + str(data)) return timestamp = int(datetime.now().timestamp()) date = str(datetime.now()) utils.myprint( 2, 'insert_marketData, timestamp: ' + str(timestamp) + ', date: ' + date) conn = sqlite3.connect(self.db) cursor = conn.cursor() # 插入指定股票的当日行情数据 sql = 'INSERT INTO %s (code, name, latest_price, opening_price, closed_price, average_price, highest_price, lowest_price, top_price, bottom_price, business_number, business_money, inflow, outflow, currency_value, total_value, increase, timestamp, date) VALUES (\'%s\', \'%s\', %f, %f, %f, %f, %f, %f, %f, %f, %d, %d, %d, %d, %d, %d, %f, %d, \'%s\')' % ( self.table_market_data, data.code, data.name, data.latest_price, data.opening_price, data.closed_price, data.average_price, data.highest_price, data.lowest_price, data.top_price, data.bottom_price, data.business_number, data.business_money, data.inflow, data.outflow, data.currency_value, data.total_value, data.increase, timestamp, date) utils.myprint(2, 'insert_marketData, insert sql: ' + str(sql)) cursor.execute(sql) cursor.close() conn.commit() conn.close()
def delete_today_marketdata(self): ''' 删除今天的行情数据,来自表 market_data :return: ''' conn = sqlite3.connect(self.db) cursor = conn.cursor() sql = 'select code, name from %s where timestamp > %d' % ( self.table_market_data, utils.get_current_day()) utils.myprint(1, 'delete_today_marketdata, sql: ' + sql) cursor.execute(sql) stocks = cursor.fetchall() if len(stocks) > 0: sql = 'delete from %s where timestamp > %d' % ( self.table_market_data, utils.get_current_day()) utils.myprint(3, 'delete_today_marketdata, sql: ' + sql) cursor.execute(sql) else: utils.myprint( 2, 'delete_today_marketdata, no data, its time > %s' % (datetime.fromtimestamp(utils.get_current_day()))) cursor.close() conn.close()
def get_stockReport(name): '''获取个股资讯,根据指定股票名字来搜索 :param name: :return: ''' response = requests.get( 'http://searchapi.eastmoney.com/bussiness/Web/GetSearchList', params={ 'type': 501, 'pageindex': 1, # 查询第几页 'pagesize': 10, # 一页多少条资讯 'keyword': name, 'name': 'normal', '_': datetime.now().timestamp() }, headers={ 'Referer': requests.get('http://so.eastmoney.com/Ann/s', params={ 'keyword': name }).url }) if response.status_code != 200: utils.myprint( 3, 'get_stockReport, http request error, status_code: ' + str(response.status_code) + ', url: ' + response.url) return None content = response.content.decode('utf-8', errors='ignore') utils.myprint(1, 'get_stockReport, http request, content: ' + content) content = json.loads(content) if not content['IsSuccess']: utils.myprint( 3, 'get_stockReport, http request, IsSuccess: False, so not Data') return None utils.myprint( 2, 'get_stockReport, http request, name: ' + name + ', TotalPage: ' + str(content['TotalPage']) + ', TotalCount: ' + str(content['TotalCount'])) infos = parse.data2stockReport(content['Data']) timestamp = utils.yanbao_filterTime() return [info for info in infos if info.report_timestamp > timestamp]
def data2stockInfo(data): '''将 json形式的数据 转换成 list,list内元素是 stock_information类对象 :param data: :return: ''' infos = [] for info in data: utils.myprint(2, 'data2stockInfo, info: ' + str(info)) # { 个股资讯的格式,来自响应内容的 "Data": Array[10] # "Art_UniqueUrl": "http://stock.eastmoney.com/a/202009091626257445.html", # "Art_Title": "<em>共达电声</em>9月9日盘中跌幅达5%", # "Art_Url": "http://stock.eastmoney.com/news/1944,202009091626257445.html", # "Art_CreateTime": "2020-09-09 10:39:33", # "Art_Content": "以下是<em>共达电声</em>在北京时间9月9日10:37分盘口异动快照:9月9日,<em>共达电声</em>盘中跌幅达5%,截至10点37分,报9.64元,成交1.85亿元,换手率5.23%。分笔10:37:549.64188↓10:37:519.65188↑10:37:489.653350↓10:37:459..." # }, infos.append( information.stock_information( info['Art_UniqueUrl'], re.sub(r'[</em><em>]', '', info['Art_Title']), info['Art_Url'], info['Art_CreateTime'], re.sub(r'[</em><em>]', '', info['Art_Content']))) return infos
def create_table_market_data(self, table_name): if type(table_name) != str or len(table_name.strip()) < 1: info = 'create_table_market_data, param[table_name: %s] invalid' % ( str(table_name)) raise Exception(info) utils.myprint( 2, 'create_table_market_data, db: ' + self.db + ', table_name: ' + table_name) conn = sqlite3.connect(self.db) cursor = conn.cursor() cursor.execute('CREATE TABLE IF NOT EXISTS %s (' 'id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, ' 'code VARCHAR(20) NOT NULL DEFAULT \'999999\', ' 'name VARCHAR(20), ' 'latest_price FLOAT, ' 'opening_price FLOAT, ' 'closed_price FLOAT, ' 'average_price FLOAT, ' 'highest_price FLOAT, ' 'lowest_price FLOAT, ' 'top_price FLOAT, ' 'bottom_price FLOAT, ' 'business_number INTEGER, ' 'business_money INTEGER, ' 'inflow INTEGER, ' 'outflow INTEGER, ' 'currency_value INTEGER, ' 'total_value INTEGER, ' 'increase FLOAT, ' 'timestamp INTEGER, ' 'date TEXT)' % (table_name)) cursor.close() conn.close()
def get_stockInfomation(name): '''获取个股资讯,根据指定股票名字来搜索 :param name: :return: ''' response = requests.get( 'http://searchapi.eastmoney.com//bussiness/Web/GetCMSSearchList', params={ 'type': 8193, 'pageindex': 1, # 查询第几页 'pagesize': 10, # 一页多少条资讯 'keyword': name, 'name': 'zixun', '_': datetime.now().timestamp() }, headers={ 'Referer': requests.get('http://so.eastmoney.com/News/s', params={ 'keyword': name }).url }) if response.status_code != 200: utils.myprint( 3, 'get_stockInfomation, http request error, status_code: ' + str(response.status_code) + ', url: ' + response.url) return None # { 请求对应的 响应内容 # "IsSuccess": true, # 判断是否请求成功 # "Code": 0, # "Message": "成功", # "TotalPage": 66, # 一共有多少页 # "TotalCount": 651, # 一共有多少条资讯 # "Keyword": "0.002655", # "Data": Array[10], # 个股资讯 # "RelatedWord": "", # "StillSearch": [ # "共达电声", # "共达电声" # ], # "StockModel": { # "Name": "共达电声", # "Code": "002655" # } content = response.content.decode('utf-8', errors='ignore') utils.myprint(1, 'get_stockInfomation, http request, content: ' + content) content = json.loads(content) if not content['IsSuccess']: utils.myprint( 3, 'get_stockInfomation, http request, IsSuccess: False, so not Data') return None utils.myprint( 2, 'get_stockInfomation, http request, name: ' + name + ', TotalPage: ' + str(content['TotalPage']) + ', TotalCount: ' + str(content['TotalCount'])) infos = parse.data2stockInfo(content['Data']) timestamp = utils.zixun_filterTime() return [info for info in infos if info.art_timestamp > timestamp]
def get_daily_makertData(code): '''获取指定股票的当日行情数据,在收盘后才可以调用 :param code: 股票代码 :return: dict类型,or None ''' if not (isinstance(code, str) or isinstance(code, int)): utils.myprint(3, 'get_daily_makertData, 参数类型不合法,code: ' + str(code)) return None if not str(code).isdigit() or len(str(code)) > 6: utils.myprint(3, 'get_daily_makertData, 参数要求不合法,code: ' + str(code)) return None if utils.is_stock_opening(): utils.myprint(2, 'get_daily_makertData, 开盘期间不建议此时同步行情数据') if str(code).startswith(('600', '601', '603')): # 沪市股票 secid = '1.%06d' % (int(code)) else: secid = '0.%06d' % (int(code)) timestamp = datetime.now().timestamp() response = requests.get( 'http://push2.eastmoney.com/api/qt/stock/get', params={ 'ut': 'fa5fd1943c7b386f172d6893dbfba10b', 'fltt': '2', 'invt': '2', 'fields': 'f120,f121,f122,f174,f175,f59,f163,f43,f57,f58,f169,f170,f46,f44,f51,f168,f47,f164,f116,f60,f45,f52,f50,f48,f167,f117,f71,f161,f49,f530,f135,f136,f137,f138,f139,f141,f142,f144,f145,f147,f148,f140,f143,f146,f149,f55,f62,f162,f92,f173,f104,f105,f84,f85,f183,f184,f185,f186,f187,f188,f189,f190,f191,f192,f107,f111,f86,f177,f78,f110,f262,f263,f264,f267,f268,f255,f256,f257,f258,f127,f199,f128,f198,f259,f260,f261,f171,f277,f278,f279,f288,f152,f250,f251,f252,f253,f254,f269,f270,f271,f272,f273,f274,f275,f276,f265,f266,f289,f290,f286,f285,f292,f293,f294,f295', 'secid': '%s' % secid, '_': timestamp }) utils.myprint(1, 'get_daily_makertData, http request, url: ' + response.url) if response.status_code != 200: utils.myprint( 3, 'get_daily_makertData, http request error, status_code: ' + str(response.status_code) + ', url: ' + response.url) return None utils.myprint( 1, 'get_daily_makertData, http request, content: ' + response.content.decode('utf-8', errors='ignore')) # json 反序列化成 Python dict content = json.loads(response.content) if 'data' in content: data = content['data'] if data is None: utils.myprint( 3, 'get_daily_makertData, data is None, code: %s, \nurl: %s' % (code, response.url)) else: data = None utils.myprint( 3, 'get_daily_makertData, no data in content, code: ' + code) utils.myprint(1, 'get_daily_makertData, return: ' + str(data)) return data