pythonK线条件选股爬虫

# coding=gbk
# @Time : 2023/7/8 0:14
# @File : 策略选股日线完整版
"""
---------大纲-----------
第一步:
获取所有非st和退市股票,非科创板的股票代号 原因: 排除大涨概率较小或者不能预测的股票
第二步:
获取所有月k线多头趋势的股票的代号(5月K线均价>30月K线均价和60月K线均价) 原因: 确定月线处于止跌趋势并且趋势反转
第三步:
获取所有周K线多头趋势的股票的代号(5周K线均价>30周K线均价>60周K线均价) 原因: 确定周线处于上涨趋势
第四步:
获取所有日K线多头趋势的股票(5日K线均价>30日K线均价>60日K线均价) 原因: 找出趋势仍是上涨的股票买入
第五步:
获取所有一季报利润增加的股票(股东净利润大于100%) 原因: 具有业绩支撑的股票跟稳定
"""
# 导入需要的模块
import requests
import json

# 创建一个csv文件,csv文件是数据和数据之间使用","隔开的文件
f = open("策略选股.csv", mode="w", encoding="utf-8")

# ---------第一步:获取所有股票代码和市场信息-----------
code_set = set() # 创建一个放置数据的空集合
# 导入headers反爬
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko)'
' Chrome/114.0.0.0 Safari/537.36 Edg/114.0.1823.82'
}
# 使用for循环遍历所有页面
for i in range(1, 274):
# 提取页面数据
param = {
'pn': f'{i}',
'pz': '20',
'po': '1',
'np': '1',
'ut': 'bd1d9ddb04089700cf9c27f6f7426281',
'fltt': '2',
'invt': '2',
'wbp2u': '6255436770793316|0|1|0|web',
'fid': 'f2',
'fs': 'm:0 t:6,m:0 t:80,m:1 t:2,m:1 t:23,m:0 t:81 s:2048',
'fields': 'f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f12,f13,f14,f15,f16,f17,f18,f20,f21,f23,f24,f25,f22,f11,f62,f128,'
'f136,f115,f152',
'_': '1688535517478',
}

url = 'http://38.push2.eastmoney.com/api/qt/clist/get' # 定义请求url

response = requests.get(url, params=param, headers=headers).text # 使用get方法获取数据进行数据解析并赋值给data
dic = json.loads(response) # 使用json.loads方法把数据转化为字典并且赋值给dic
diff = dic['data']['diff'] # 把数据转换为字典的形式提取出来
for pd in diff: # 通过for循环拿到需要的数据
price = pd["f2"] # 股票价格
name = pd["f14"] # 股票名称
code = pd["f12"] # 股票代码
market = pd["f13"] # 获取股票板块
if price == '-': # 如果(股票价格)price='-'
price = 0.0 # 股票价格为0
price = float(price) # 把price的数据类型转换为float类型
market = str(market) # 把market的数据类型转换为str类型
code_data = market + '.' + code # 获取所有股票的市场代号
# 判断股票名称中是否含有"ST"(剔除st股票),判断股票名称中是否含有"退市"(剔除退市股票),判断是否以3开头(剔除创业板股票),
# 判断代码里是否有"688"(剔除科技版股票),股价是否小于40元,如果没有就写入到csv文件中,如果有就跳过不写入
if name.find("ST") == -1 and name.find("退") == -1 and not code.startswith("300") and code.find("688") and\
40.0 > price > 5:
code_set.add(code_data) # 把数据'coda_data'放到集合code_set里面
print('第一步:获取所有符合条件股票信息完成')

# ---------第二步:获取所有符合月k线条件的股票信息-------

ma_mouth_klines = set() # 创建一个放置数据的空集合
for m in code_set: # 循环获取需要请求url
url = 'http://23.push2his.eastmoney.com/api/qt/stock/kline/get?&secid={}&ut=fa5fd1943c7b386f172d6893dbfba10b&' \
'fields1=f1%2Cf2%2Cf3%2Cf4%2Cf5%2Cf6&fields2=f51%2Cf52%2Cf53%2Cf54%2Cf55%2Cf56%2Cf57%2Cf58%2Cf59%2Cf60%' \
'2Cf61&klt=103&fqt=1&beg=0&end=20500101&smplmt=460&lmt=1000000&_=1688541855749'.format(m)

response = requests.get(url, headers=headers).text # 使用get方法获取数据进行数据解析并赋值给data
dic = json.loads(response) # 使用json.loads方法把数据转化为字典并且赋值给dic
diff = dic['data'] # 把字典dic中data的值赋值给diff
code = diff['code'] # code赋值给code(代码)
market = diff['market'] # market赋值给market(市场)
market = str(market) # 把market的数据类型转换为market
ma_code_data = market + '.' + code # 获取所有符合月线的股票的市场代号
name = diff['name'] # name赋值给name(名字)
klines = diff['klines'] # klines赋值给klines(K线)
split_data = [item.split(',') for item in klines] # 将每个字符串按逗号分割成子列表
data_index_2 = [item[2] for item in split_data] # 使用列表推导式获取每个子列表下标为2的数据
my_list = list(map(float, data_index_2)) # 使用map()函数将列表中的数据转换为float类型
last_five = my_list[-5:] # 获取后5个元素
last_thirty = my_list[-30:] # 获取后30个元素
last_sixty = my_list[-60:] # 获取后60个元素

if len(my_list) > 0: # 在列表不为空时执行的代码
price = my_list[-1] # 把my_list[-1]的值赋值给price(价格)
else:
continue
if len(last_sixty) < 60: # 判断last_sixty是否有60个数据
continue
else:
average5 = round(sum(last_five) / len(last_five), 2) # 计算平均值,计算平均值并保留两位小数
average30 = round(sum(last_thirty) / len(last_thirty), 2) # 计算平均值,计算平均值并保留两位小数
average60 = round(sum(last_sixty) / len(last_sixty), 2) # 计算平均值,计算平均值并保留两位小数
price1 = average5 - average60 # 计算5月k线减去60日月K线的差
price2 = average60 - average30 # 计算60月k线减去30日月K线的差
if price1 > price2: # 找出月K线符合条件的股票(价格不高于60月K线1.5倍)
if average5 > average60 > average30: # 找出月K线符合条件的股票(5>60>30)
ma_mouth_klines.add(ma_code_data) # 把数据'ma_code_data'放到集合ma_mouth_klines里面
print('第二步:获取所有符合月k线条件的股票信息完成')

# ---------第三步:获取所有符合周k线条件的股票信息-------

ma_week_klines = set() # 创建一个放置数据的空集合
for w in ma_mouth_klines: # 循环需要请求url
url = 'http://2.push2his.eastmoney.com/api/qt/stock/kline/get?&secid={}&ut=fa5fd1943c7b386f172d6893dbfba10b&' \
'fields1=f1%2Cf2%2Cf3%2Cf4%2Cf5%2Cf6&fields2=f51%2Cf52%2Cf53%2Cf54%2Cf55%2Cf56%2Cf57%2Cf58%2Cf59%2Cf60' \
'%2Cf61&klt=102&fqt=1&end=20500101&lmt=120&_=1688749328832'.format(w)

response = requests.get(url, headers=headers).text # 使用get方法获取数据进行数据解析并赋值给data
dic = json.loads(response) # 使用json.loads方法把数据转化为字典并且赋值给dic
diff = dic['data'] # 把字典dic中data的值赋值给diff
code = diff['code'] # code赋值给code(代码)
market = diff['market'] # market赋值给market(市场)
market = str(market) # 把market的数据类型转换为market
ma_code_data = market + '.' + code # 获取所有符合月线的股票的市场代号
name = diff['name'] # name赋值给name(名字)
klines = diff['klines'] # klines赋值给klines(K线)
split_data = [item.split(',') for item in klines] # 将每个字符串按逗号分割成子列表
data_index_2 = [item[2] for item in split_data] # 使用列表推导式获取每个子列表下标为2的数据
my_list = list(map(float, data_index_2)) # 使用map()函数将列表中的数据转换为float类型
last_five = my_list[-5:] # 获取后5个元素
average5 = round(sum(last_five) / len(last_five), 2) # 计算平均值,计算平均值并保留两位小数
last_thirty = my_list[-30:] # 获取后30个元素
average30 = round(sum(last_thirty) / len(last_thirty), 2) # 计算平均值,计算平均值并保留两位小数
last_sixty = my_list[-60:] # 获取后60个元素
average60 = round(sum(last_sixty) / len(last_sixty), 2) # 计算平均值,计算平均值并保留两位小数
if average5 > average30 > average60: # 找出周K线符合条件的股票(5>30>60)
ma_week_klines.add(ma_code_data) # 把数据'ma_code_data'放到集合ma_week_klines里面
print('第三步:获取所有符合周k线条件的股票信息完成')

# ---------第四步:获取所有符合日k线条件的股票信息-------

ma_day_klines = set() # 创建一个放置数据的空集合
for d in ma_week_klines: # 循环需要请求url
url = 'http://64.push2his.eastmoney.com/api/qt/stock/kline/get?&secid={}&ut=fa5fd1943c7b386f172d6893db' \
'fba10b&fields1=f1%2Cf2%2Cf3%2Cf4%2Cf5%2Cf6&fields2=f51%2Cf52%2Cf53%2Cf54%2Cf55%2Cf56%2Cf57%2Cf58%2Cf5' \
'9%2Cf60%2Cf61&klt=101&fqt=1&end=20500101&lmt=120&_=1688749328894'.format(d)

response = requests.get(url, headers=headers).text # 使用get方法获取数据进行数据解析并赋值给data
dic = json.loads(response) # 使用json.loads方法把数据转化为字典并且赋值给dic
diff = dic['data'] # 把字典dic中data的值赋值给diff
code = diff['code'] # code赋值给code(代码)
klines = diff['klines'] # klines赋值给klines(K线)
split_data = [item.split(',') for item in klines] # 将每个字符串按逗号分割成子列表
data_index_2 = [item[2] for item in split_data] # 使用列表推导式获取每个子列表下标为2的数据
my_list = list(map(float, data_index_2)) # 使用map()函数将列表中的数据转换为float类型
last_five = my_list[-5:] # 获取后5个元素
average5 = round(sum(last_five) / len(last_five), 2) # 计算平均值,计算平均值并保留两位小数
last_thirty = my_list[-30:] # 获取后30个元素
average30 = round(sum(last_thirty) / len(last_thirty), 2) # 计算平均值,计算平均值并保留两位小数
last_sixty = my_list[-60:] # 获取后60个元素
average60 = round(sum(last_sixty) / len(last_sixty), 2) # 计算平均值,计算平均值并保留两位小数
if average5 > average30 > average60: # 找出日K线符合条件的股票(5>30>60)
ma_day_klines.add(code) # 把数据code放到集合ma_day_klines里面

print('第四步:获取所有符合日k线条件的股票信息完成')

# ---------第五步:获取所有利润增长符合条件的股票信息-------

for money in ma_day_klines: # 循环需要请求url
url = 'https://datacenter-web.eastmoney.com/api/data/v1/get?sortColumns=REPORTDATE&sortTypes=-1&pageSize=50&' \
'pageNumber=1&columns=ALL&filter=(SECURITY_CODE%3D%22{}%22)&reportName=RPT_LICO_FN_CPD'.format(money)
response = requests.get(url).text # 使用get方法获取数据进行数据解析并赋值给data
dic = json.loads(response) # 使用json.loads方法把数据转化为字典并且赋值给dic
diff = dic['result']['data'] # 把数据转换为字典的形式提取出来
Common_size = diff[0] # 获取第一个列表下标为0的数据(最新一期的一季报)
net_margin = Common_size['SJLTZ'] # 新季报同比净利润增长率
code = Common_size['SECURITY_CODE'] # 股票代码
name = Common_size['SECURITY_NAME_ABBR'] # 股票名称
if net_margin > 100.0: # 找出所有利润增长大于50%的股票
f.write(f"{name}\n{code}\n") # 把数据code,name写入csv文件里面

print('第五步:获取所有利润增长符合条件的股票信息完成')
f.close()
print("运行结束")

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值