python抓取申万Ⅲ级分类数据并保存到文本文件和PostgreSQL

本文为抓取申万Ⅲ级分类板块数据并保存到文本文件和数据库PostgreSQL的应用示例,并附有完整代码。抓取数据内容包括个股的申万Ⅲ级分类代码、申万Ⅲ级分类名称、个股代码、个股名称、总市值、流通市值、最新价和换手率。

完整代码如下:


import requests
from bs4 import BeautifulSoup
import re
from operator import itemgetter
import time
import random
import pandas as pd

from psycopg2 import Error
import psycopg2
import psycopg2.extras as extras
import sys
from io import StringIO,BytesIO
from psycopg2.extensions import ISOLATION_LEVEL_AUTOCOMMIT

def remove_col(arr, ith):
    itg = itemgetter(*filter((ith).__ne__, range(len(arr[0]))))
    return list(map(list, map(itg, arr))) 

url = 'http://vip.stock.finance.sina.com.cn/quotes_service/api/json_v2.php/Market_Center.getHQNodes'

heads = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.90 Safari/537.36"}

resText = requests.get(url)

soup = BeautifulSoup(resText.content, features='lxml')
# soup = BeautifulSoup(resText.text, "html.parser")

s = soup.text

print('\n申万三级分类:')  
shw3 = s[s.find('sw2_hy'):s.find('sw3_hy')]
shw3_cut = shw3[shw3.find('[['):shw3.find(']]')]
shw3_cut = re.sub(r'\[','',shw3_cut)
shw3_list = shw3_cut.split(']')
shw3_list_split = []
for i in range(0,len(shw3_list)):
    item_split = shw3_list[i].split(',')
    if i == 0:        
        temp_str = item_split[0].encode('utf-8').decode('unicode_escape')
        item_split[0] = temp_str
    else:
        temp_str = item_split[1].encode('utf-8').decode('unicode_escape')
        item_split[1] = temp_str
        item_split = item_split[1:4]   
    shw3_list_split.append(item_split)  
result_shw3 = remove_col(shw3_list_split, 1)
print()
print('申万三级分类总数:',len(result_shw3))
print(result_shw3[0:3])

## 申万三级级分类及其各分类下的股票, sw2_730100
print('申万三级及其所属股票')
shw3_category_and_stocks = []
shw3_categorystock = []
for i in range(0,len(result_shw3)): #len(result_shw3)
    url3 = 'http://vip.stock.finance.sina.com.cn/quotes_service/api/json_v2.php/Market_Center.getHQNodeData?page=1&num=500&sort=symbol&asc=1&node=' + result_shw3[i][1][1:11] + '&symbol=&_s_r_a=init'   
    print(url3,i,result_shw3[i][0],result_shw3[i][1][1:11])
    
    resText3 = requests.get(url3)
    soup3 = BeautifulSoup(resText3.content, features='lxml') 
    s3 = soup3.text
    
    resStr3 = re.sub(r'\[','',s3)
    resStr3 = re.sub(r'\]','',resStr3) 
    resStr3 = re.sub(r'{','',resStr3) 

    resStr3_list = resStr3.split('}')
    resStr3_list.pop() # 删除最后一个元素,由于split产生的空元素   

    shw_three_stocks = []    
    for j in range(0, len(resStr3_list)):    
        singlestock_info = resStr3_list[j].split(',')
        if j == 0:        
            rst = [[x for x in ss.split(':')] for ss in singlestock_info]                               
            shw_three_stocks.append([rst[0][1][1:len(rst[0][1])-1],rst[1][1][1:len(rst[1][1])-1],rst[2][1][1:len(rst[2][1])-1].encode('utf-8').decode('unicode_escape'),rst[-3][1],rst[-2][1],rst[3][1][1:-1],rst[-1][1][1:-1]])
            shw3_categorystock.append([result_shw3[i][0][1:len(result_shw3[i][0])-1],
                                       result_shw3[i][1][1:len(result_shw3[i][1])-1],
                                       rst[0][1][1:len(rst[0][1])-1],
                                       rst[1][1][1:len(rst[1][1])-1],
                                       rst[2][1][1:len(rst[2][1])-1].encode('utf-8').decode('unicode_escape'),
                                       round(float(rst[-3][1]),2), # 总市值
                                       round(float(rst[-2][1]),2),  # 流通市值
                                       round(float(rst[3][1][1:-1]),2), # 最新价
                                       rst[-1][1][1:-1] # 换手率
                                       ])
        else: 
            rst = [[x for x in ss.split(':')] for ss in singlestock_info]                              
            shw_three_stocks.append([rst[1][1][1:len(rst[1][1])-1],rst[2][1][1:len(rst[2][1])-1],rst[3][1][1:len(rst[3][1])-1].encode('utf-8').decode('unicode_escape'),rst[-3][1],rst[-2][1],rst[4][1][1:-1],rst[-1][1][1:-1]])
            shw3_categorystock.append([result_shw3[i][0][1:len(result_shw3[i][0])-1],
                                       result_shw3[i][1][1:len(result_shw3[i][1])-1], 
                                       rst[1][1][1:len(rst[1][1])-1],rst[2][1][1:len(rst[2][1])-1],
                                       rst[3][1][1:len(rst[3][1])-1].encode('utf-8').decode('unicode_escape'),
                                       round(float(rst[-3][1]),2), # 总市值
                                       round(float(rst[-2][1]),2),  # 流通市值
                                       round(float(rst[4][1][1:-1]),2), # 最新价
                                       rst[-1][1][1:-1] # 换手率
                                       ])

    tmp_removequotes = [result_shw3[i][0][1:len(result_shw3[i][0])-1],result_shw3[i][1][1:len(result_shw3[i][1])-1]]
    shw3_category_and_stocks.append([tmp_removequotes,'A',shw_three_stocks])
    time.sleep(random.randint(1,6)) #防止抓取页面密集而网站被封

print()
with open('shw3category_details.csv','w') as fobj:  #仅用于测试观察数据    
    for i in range(0,len(shw3_category_and_stocks)):    
        print(f'{shw3_category_and_stocks[i]},')        
        fobj.write(str(shw3_category_and_stocks[i])+'\n')              
        # print(shw3_category_and_stocks[i][1])

print()
print('申万三级分类总数:',len(result_shw3))
print('申万三级分类总数(包括各分类的股票):',len(shw3_category_and_stocks))

shw3_category = [x[0][0] for x in shw3_category_and_stocks] 
shw3_code = [x[0][1] for x in shw3_category_and_stocks] 
dict3 = {'shw3_code': shw3_code,'shw3_category': shw3_category} 
df3 = pd.DataFrame(dict3) 
df3.to_csv('shenwan3_category.csv',index = False)

shw3_category_code =  [x[1] for x in shw3_categorystock] 
shw3_category_name =  [x[0] for x in shw3_categorystock] 
shw3_category_mktcode =  [x[2] for x in shw3_categorystock] 
shw3_stock_code =  [x[3] for x in shw3_categorystock] 
shw3_stock_name =  [x[4] for x in shw3_categorystock] 
stock_mktcap = [x[5] for x in shw3_categorystock] 
stock_nmc = [x[6] for x in shw3_categorystock] 
stock_price = [x[7] for x in shw3_categorystock] 
turnoverratio = [x[8] if not x[8] == '' else '0' for x in shw3_categorystock] 
dict3 = {'shw3_code': shw3_category_code,'category_name': shw3_category_name,'category_mktcode':shw3_category_mktcode,\
         'stock_code':shw3_stock_code,'stock_name':shw3_stock_name,'stock_mktcap':stock_mktcap,'stock_nmc':stock_nmc,'stock_price':stock_price,'turnoverratio:':turnoverratio}  # 
df3 = pd.DataFrame(dict3) 
df3.to_csv('shenwan3_category_stocks.csv',index = False)

stocks_hsl = list(zip(shw3_category_code,shw3_category_name,shw3_category_mktcode,shw3_stock_code,shw3_stock_name,stock_mktcap,stock_nmc,stock_price,turnoverratio))

print('\n 确定是否保存个股换手率数据到数据库 PostgreSQL ')
choosing_method = int(input("\n 输入1 - 保存, 输入2 - 不保存, 默认为 2: "))
if choosing_method == 1:
    print("选择 " +str(choosing_method)+' , 保存数据到数据表 stocks_hsl ... ' )
    try:
        conn = psycopg2.connect(
            host="localhost",
            database="stockdb",
            user="postgres",
            password="******"
        )
        # 打开允许批量插入的游标
        cur = conn.cursor()
        # 执行批量插入操作(使用忽略唯一键错误的方式)        
        sql = "INSERT INTO stocks_hsl " + \
            "(shw3_code,category_name,category_mktcode,stock_code,stock_name,stock_mktcap,stock_nmc,stock_price,turnoverratio)" + \
            "VALUES (%s, %s,%s, %s,%s, %s,%s, %s,%s) ON CONFLICT DO NOTHING"
        
        cur.executemany(sql, stocks_hsl)
        # 提交事务
        conn.commit()
    except (Exception, Error) as e:
        print(" 连接 PostgreSQL 时报错!", e)
    finally:
        # 关闭游标和连接
        if cur:
            cur.close()
        if conn:
            conn.close()    
else:
    print('本次不保存个股换手率数据到数据库')    



#  ['"sz000070"', '"000070"', '"特发信息"', '"5.860"', '0.04', '0.687', '"5.850"', '"5.860"', '"5.820"', 
# '"5.810"', '"5.860"', '"5.660"', '8478528', '48999967', '2022-06-14', '-7.808', '2.588', '494924.355832', '487960.883258', '1.0182']

## 字段说明
# "symbol":"sz002281",
# "code":"002281",
# "name":"\u5149\u8fc5\u79d1\u6280",
# "trade":"22.740",
# "pricechange":-0.29,
# "changepercent":-1.259,
# "buy":"22.740",
# "sell":"22.750",
# "settlement":"23.030", 昨日收盘价
# "open":"23.050",
# "high":"23.220",
# "low":"22.670",
# "volume":6874488, 成交量
# "amount":157353968, 成交额
# "ticktime":"15:00:03",
# "per":31.151,
# "pb":2.905, 市净率
# "mktcap":1590455.879532, 总市值
# "nmc":1507701.365214, 流通市值
# "turnoverratio":1.03685, 换手率

申万Ⅲ级板块分类,共336类

shw3_code,shw3_category
sw3_240602,镍
sw3_720706,其他数字媒体
sw3_770302,医美服务
sw3_770301,医美耗材
sw3_770202,品牌化妆品
sw3_770201,化妆品制造及其他
sw3_770102,洗护用品
sw3_770101,生活用纸
sw3_760201,环保设备Ⅲ
sw3_760104,综合环境治理
sw3_760103,固废治理
sw3_760102,水务及水治理
sw3_760101,大气治理
sw3_750303,其他石化
sw3_750302,油品石化贸易
sw3_750301,炼油化工
sw3_750202,油气及炼化工程
sw3_750201,油田服务
sw3_750101,油气开采Ⅲ
sw3_740201,焦炭Ⅲ
sw3_740102,焦煤
sw3_740101,动力煤
sw3_730207,其他通信设备
sw3_730206,通信终端及配件
sw3_730205,通信线缆及配套
sw3_730204,通信网络设备及器件
sw3_730104,通信应用增值服务
sw3_730103,通信工程及服务
sw3_730102,电信运营商
sw3_721001,电视广播Ⅲ
sw3_720902,大众出版
sw3_720901,教育出版
sw3_720705,文字媒体
sw3_720704,门户网站
sw3_720703,图片媒体
sw3_720701,视频媒体
sw3_720602,院线
sw3_720601,影视动漫制作
sw3_720502,广告媒体
sw3_720501,营销代理
sw3_720401,游戏Ⅲ
sw3_710402,横向通用软件
sw3_710401,垂直应用软件
sw3_710301,IT服务Ⅲ
sw3_710103,其他计算机设备
sw3_710102,安防设备
sw3_650501,军工电子Ⅲ
sw3_640704,其他自动化设备
sw3_640703,激光设备
sw3_640702,工控设备
sw3_640701,机器人
sw3_640602,工程机械器件
sw3_640601,工程机械整机
sw3_640108,金属制品
sw3_640107,仪器仪表
sw3_630805,线缆部件及其他
sw3_630804,电工仪器仪表
sw3_630803,电网自动化设备
sw3_630802,配电设备
sw3_630801,输变电设备
sw3_630705,蓄电池及其他电池
sw3_630704,燃料电池
sw3_630703,锂电专用设备
sw3_630702,电池化学品
sw3_630701,锂电池
sw3_630602,风电零部件
sw3_630601,风电整机
sw3_630505,光伏加工设备
sw3_630504,光伏辅材
sw3_630503,逆变器
sw3_630502,光伏电池组件
sw3_630501,硅料硅片
sw3_620601,工程咨询服务Ⅲ
sw3_620307,园林工程
sw3_620306,基建市政工程
sw3_610305,涂料
sw3_610304,防水材料
sw3_610202,玻纤制造
sw3_610102,水泥制品
sw3_490308,其他多元金融
sw3_490307,资产管理
sw3_490306,金融信息服务
sw3_490305,租赁
sw3_490304,信托
sw3_490303,期货
sw3_490302,金融控股
sw3_480501,农商行Ⅲ
sw3_480401,城商行Ⅲ
sw3_480301,股份制银行Ⅲ
sw3_480201,国有大型银行Ⅲ
sw3_461103,教育运营及其他
sw3_461102,培训教育
sw3_461101,学历教育
sw3_461004,旅游综合
sw3_461003,自然景区
sw3_461002,人工景区
sw3_460902,餐饮
sw3_460901,酒店
sw3_460804,其他专业服务
sw3_460803,会展服务
sw3_460802,检测服务
sw3_460801,人力资源服务
sw3_460601,体育Ⅲ
sw3_450701,旅游零售Ⅲ
sw3_450603,电商服务
sw3_450602,跨境电商
sw3_450601,综合电商
sw3_450304,商业物业经营
sw3_430302,房产租赁经纪
sw3_430301,物业管理
sw3_430103,产业地产
sw3_430102,商业地产
sw3_421102,港口
sw3_421101,航运
sw3_421002,机场
sw3_421001,航空运输
sw3_420903,铁路运输
sw3_420902,公交
sw3_420901,高速公路
sw3_420807,公路货运
sw3_420806,仓储物流
sw3_420805,跨境物流
sw3_420804,快递
sw3_420803,中间产品及消费品供应链服务
sw3_420802,原材料供应链服务
sw3_410110,电能综合服务
sw3_410109,其他能源发电
sw3_410108,核力发电
sw3_410107,风力发电
sw3_410106,光伏发电
sw3_370605,其他医疗服务
sw3_370604,医院
sw3_370603,医疗研发外包
sw3_370602,诊断服务
sw3_370504,体外诊断
sw3_370503,医疗耗材
sw3_370502,医疗设备
sw3_370403,线下药店
sw3_370402,医药流通
sw3_370304,其他生物制品
sw3_370303,疫苗
sw3_370302,血液制品
sw3_360502,娱乐用品
sw3_360501,文化用品
sw3_360311,其他家居用品
sw3_360309,卫浴制品
sw3_360308,定制家居
sw3_360307,成品家居
sw3_360306,瓷砖地板
sw3_360206,综合包装
sw3_360205,纸包装
sw3_360204,塑料包装
sw3_360203,金属包装
sw3_360202,印刷
sw3_360103,特种纸
sw3_360102,大宗用纸
sw3_350303,其他饰品
sw3_350301,钟表珠宝
sw3_350209,非运动服装
sw3_350208,运动服装
sw3_350107,纺织鞋类制造
sw3_340901,调味发酵品Ⅲ
sw3_340803,熟食
sw3_340802,烘焙食品
sw3_340801,零食
sw3_340702,乳品
sw3_340701,软饮料
sw3_340602,其他酒类
sw3_340601,啤酒
sw3_340501,白酒Ⅲ
sw3_340407,保健品
sw3_340406,预加工食品
sw3_330701,其他家电Ⅲ
sw3_330601,家电零部件Ⅲ
sw3_330501,照明设备Ⅲ
sw3_330402,卫浴电器
sw3_330401,厨房电器
sw3_330303,个护小家电
sw3_330302,清洁小家电
sw3_330301,厨房小家电
sw3_330106,冰洗
sw3_280602,商用载客车
sw3_280601,商用载货车
sw3_280502,综合乘用车
sw3_280501,电动乘用车
sw3_280402,摩托车
sw3_280303,汽车综合服务
sw3_280302,汽车经销商
sw3_280206,汽车电子电气系统
sw3_280205,其他汽车零部件
sw3_280204,轮胎轮毂
sw3_280203,底盘与发动机系统
sw3_280202,车身附件及饰件
sw3_270601,电子化学品Ⅲ
sw3_270504,消费电子零部件及组装
sw3_270503,品牌消费电子
sw3_270108,半导体设备
sw3_270107,集成电路封测
sw3_270106,集成电路制造
sw3_270105,模拟芯片设计
sw3_270104,数字芯片设计
sw3_240603,锂
sw3_240601,钴
sw3_240505,钼
sw3_240402,白银
sw3_230501,特钢Ⅲ
sw3_230403,钢铁管材
sw3_230402,板材
sw3_230401,长材
sw3_230302,冶钢辅料
sw3_230301,铁矿石
sw3_220901,非金属材料Ⅲ
sw3_220805,复合肥
sw3_220804,钾肥
sw3_220803,农药
sw3_220802,磷肥及磷化工
sw3_220801,氮肥
sw3_220604,橡胶助剂
sw3_220505,膜材料
sw3_220504,合成树脂
sw3_220406,锦纶
sw3_220317,胶黏剂及胶带
sw3_220316,有机硅
sw3_220315,食品及饲料添加剂
sw3_220206,钛白粉
sw3_220205,煤化工
sw3_110901,农业综合Ⅲ
sw3_110704,其他养殖
sw3_110703,肉鸡养殖
sw3_110702,生猪养殖
sw3_110404,宠物食品
sw3_110403,水产饲料
sw3_110402,畜禽饲料
sw3_110104,食用菌
sw3_650401,航海装备Ⅲ
sw3_650301,地面兵装Ⅲ
sw3_650201,航空装备Ⅲ
sw3_650101,航天装备Ⅲ
sw3_640501,轨交设备Ⅲ
sw3_640209,其他专用设备
sw3_640208,印刷包装机械
sw3_640207,农用机械
sw3_640206,纺织服装设备
sw3_640204,楼宇设备
sw3_640203,能源及重型设备
sw3_640106,其他通用设备
sw3_640105,制冷空调设备
sw3_640103,磨具磨料
sw3_640101,机床工具
sw3_630306,其他电源设备Ⅲ
sw3_630304,火电设备
sw3_630301,综合电力设备商
sw3_630101,电机Ⅲ
sw3_620404,其他专业工程
sw3_620403,国际工程
sw3_620402,化学工程
sw3_620401,钢结构
sw3_620201,装修装饰Ⅲ
sw3_620101,房屋建设Ⅲ
sw3_610303,其他建材
sw3_610302,管材
sw3_610301,耐火材料
sw3_610201,玻璃制造
sw3_610101,水泥制造
sw3_510101,综合Ⅲ
sw3_490201,保险Ⅲ
sw3_490101,证券Ⅲ
sw3_450401,专业连锁Ⅲ
sw3_450303,多业态零售
sw3_450302,超市
sw3_450301,百货
sw3_450201,贸易Ⅲ
sw3_430101,住宅开发
sw3_410301,燃气Ⅲ
sw3_410104,热力服务
sw3_410102,水力发电
sw3_410101,火力发电
sw3_370201,中药Ⅲ
sw3_370102,化学制剂
sw3_370101,原料药
sw3_350206,家纺
sw3_350205,鞋帽及其他
sw3_350106,其他纺织
sw3_350105,辅料
sw3_350104,印染
sw3_350102,棉纺
sw3_340401,肉制品
sw3_330202,其他黑色家电
sw3_330201,彩电
sw3_330102,空调
sw3_280401,其他运输设备
sw3_270401,其他电子Ⅲ
sw3_270303,光学元件
sw3_270302,LED
sw3_270301,面板
sw3_270203,被动元件
sw3_270202,印制电路板
sw3_270103,半导体材料
sw3_270102,分立器件
sw3_240504,其他小金属
sw3_240502,钨
sw3_240501,稀土
sw3_240401,黄金
sw3_240303,铅锌
sw3_240302,铜
sw3_240301,铝
sw3_240202,磁性材料
sw3_240201,其他金属新材料
sw3_220603,炭黑
sw3_220602,其他橡胶制品
sw3_220503,改性塑料
sw3_220501,其他塑料制品
sw3_220405,氨纶
sw3_220404,其他化学纤维
sw3_220403,粘胶
sw3_220401,涤纶
sw3_220313,聚氨酯
sw3_220311,氟化工
sw3_220309,其他化学制品
sw3_220308,纺织化学制品
sw3_220307,民爆制品
sw3_220305,涂料油墨
sw3_220204,其他化学原料
sw3_220203,无机盐
sw3_220202,氯碱
sw3_220201,纯碱
sw3_110801,动物保健Ⅲ
sw3_110504,其他农产品加工
sw3_110502,粮油加工
sw3_110501,果蔬加工
sw3_110301,林业Ⅲ
sw3_110202,水产养殖
sw3_110201,海洋捕捞
sw3_110103,其他种植业
sw3_110102,粮食种植
sw3_110101,种子

发布者:股市刺客,转载请注明出处:https://www.95sca.cn/archives/73787
站内所有文章皆来自网络转载或读者投稿,请勿用于商业用途。如有侵权、不妥之处,请联系站长并出示版权证明以便删除。敬请谅解!

(0)
股市刺客的头像股市刺客
上一篇 2024 年 7 月 10 日
下一篇 2024 年 7 月 10 日

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注