美股交流群 微信群 程序化交易

自己在网上找了一批,发现没几个可以加。索性自己建一个群,大家一起来加入吧。
因为会过期,所以需要的人可以在公众号后台回复:加美股群
 
就可以加入啦。
 
公众号:
继续阅读 »
自己在网上找了一批,发现没几个可以加。索性自己建一个群,大家一起来加入吧。
因为会过期,所以需要的人可以在公众号后台回复:加美股群
 
就可以加入啦。
 
公众号:
收起阅读 »

etf全球投资指南 PDF电子书 高清完整版 读后感 & 电子书下载

读后感:
1. 原有有做空A股的ETF
2. 投资不同国家的ETF的方式。前提需要有一个美股账号。 这个国内开通也很方便的,就入金的时候有点麻烦。
 
PDF word高清版

xXKRWHcqGn.png

 
下载地址:关注微信公众:

 
后台回复:
etf全球投资指南
 
即可
 
继续阅读 »
读后感:
1. 原有有做空A股的ETF
2. 投资不同国家的ETF的方式。前提需要有一个美股账号。 这个国内开通也很方便的,就入金的时候有点麻烦。
 
PDF word高清版

xXKRWHcqGn.png

 
下载地址:关注微信公众:

 
后台回复:
etf全球投资指南
 
即可
  收起阅读 »

可转债发行的流程

发行流程:董事会预案 → 股东大会批准 → 证监会受理 → 发审委通过 → 证监会核准/同意注册 → 发行公告 
 
可转债低费率开户,费率十万分之四,没有最低收费限制。
可联系:

 
备注开户
继续阅读 »
发行流程:董事会预案 → 股东大会批准 → 证监会受理 → 发审委通过 → 证监会核准/同意注册 → 发行公告 
 
可转债低费率开户,费率十万分之四,没有最低收费限制。
可联系:

 
备注开户 收起阅读 »

flask自定义所有错误返回json格式

使用app.register_error_andler绑定时,把debug=True去掉才可以。
使用app.register_error_andler绑定时,把debug=True去掉才可以。

python获取指定类型的最新股票公告

比如个人比较关注套利基金LOF,所以主要爬取的公告是LOF的
M7ENbhD4ve.png


C74upMwH5x.png

 
然后通过NLP分析公告内容,过滤出个人想要的内容。
 
关注个人公众号,获取更多内容
继续阅读 »
比如个人比较关注套利基金LOF,所以主要爬取的公告是LOF的
M7ENbhD4ve.png


C74upMwH5x.png

 
然后通过NLP分析公告内容,过滤出个人想要的内容。
 
关注个人公众号,获取更多内容
收起阅读 »

csdn网站就不能优化下的么,在远程桌面访问卡得要命

加了没有必要得背景特效,弄得在远程桌面下渲染效果极为卡顿。
现在搜索出来得结果见到csdn得就得躲得远远得。
一来本身质量不行,都是抄来抄去
加了没有必要得背景特效,弄得在远程桌面下渲染效果极为卡顿。
现在搜索出来得结果见到csdn得就得躲得远远得。
一来本身质量不行,都是抄来抄去

微信gif 大小不能超过50K,不然就当做文件发送,无法显示的

估计是影响图片的动态显示性能。
只能把图片压缩一下,或者去除一些无用帧
估计是影响图片的动态显示性能。
只能把图片压缩一下,或者去除一些无用帧

优矿的可转债的YTM数据为空 nan

获取函数:
DataAPI.MktBonddGet(secID=u"",ticker=u"122560",tradeDate=u"",beginDate=u"20180301",endDate=u"20180315",field=u"",pandas="1")

注意YTM哪一列全是Nan

loDPX1TA71.png

 
脏数据太多了,吐槽一波。
继续阅读 »
获取函数:
DataAPI.MktBonddGet(secID=u"",ticker=u"122560",tradeDate=u"",beginDate=u"20180301",endDate=u"20180315",field=u"",pandas="1")

注意YTM哪一列全是Nan

loDPX1TA71.png

 
脏数据太多了,吐槽一波。 收起阅读 »

pandas 合并两个表,如何保留第一个表的索引?

df1 数据
 tickerBond  closePriceBond  bondPremRatio secShortNameBond tickerEqu  \
secID
110066 110066 199.94 -1.2442 盛屯转债 600711
110067 110067 119.53 25.9204 华安转债 600909
113021 113021 105.81 45.0989 中信转债 601998
113024 113024 101.94 36.6668 核建转债 601611
113025 113025 129.16 0.0409 明泰转债 601677

df2 数据
        ROE tickerEqu
0 2.642931 600711
1 4.425438 600909
2 6.259092 601998
3 4.432315 601611
4 6.454054 601677

如果按照 pd.merge(df1,df2,on='tickerEqu') ,按照列 tickerEqu 进行合并,这样会导致最后合成的新的列的索性重构,变成 0,1,2,3 这种的。

有什么办法可以保留 df1 的索引? 用 join 的话会报错,因为 df2 的索引和 df1 匹配不上。
 
先 df1 = df1.reset_index(),合并之后再把 secID 那一列设为 index 。
继续阅读 »
df1 数据
 tickerBond  closePriceBond  bondPremRatio secShortNameBond tickerEqu  \
secID
110066 110066 199.94 -1.2442 盛屯转债 600711
110067 110067 119.53 25.9204 华安转债 600909
113021 113021 105.81 45.0989 中信转债 601998
113024 113024 101.94 36.6668 核建转债 601611
113025 113025 129.16 0.0409 明泰转债 601677

df2 数据
        ROE tickerEqu
0 2.642931 600711
1 4.425438 600909
2 6.259092 601998
3 4.432315 601611
4 6.454054 601677

如果按照 pd.merge(df1,df2,on='tickerEqu') ,按照列 tickerEqu 进行合并,这样会导致最后合成的新的列的索性重构,变成 0,1,2,3 这种的。

有什么办法可以保留 df1 的索引? 用 join 的话会报错,因为 df2 的索引和 df1 匹配不上。
 
先 df1 = df1.reset_index(),合并之后再把 secID 那一列设为 index 。
收起阅读 »

李笑来:普通人如何练习做到深入思考

李笑来:
普通人如何练习做到深入思考?
喜欢和聪明人打交道

1. 聪明人的定义:
对一些清晰,必要,准确的概念,很明白,没必要的东西可能就被抛弃。
聪明不是天生的,而是长期积累,锻炼。
我不相信聪明人赚不到钱。

如何锻炼:
 
同一个问题,经常去想,就会比别人想的深刻,周全。
 
对一件事情想象得深刻,并不是靠聪明就可以做得来的。
 
独立的时间,空间,不干扰。

别忘了问题,天天想,想得比别人多,足够多。
继续阅读 »
李笑来:
普通人如何练习做到深入思考?
喜欢和聪明人打交道

1. 聪明人的定义:
对一些清晰,必要,准确的概念,很明白,没必要的东西可能就被抛弃。
聪明不是天生的,而是长期积累,锻炼。
我不相信聪明人赚不到钱。

如何锻炼:
 
同一个问题,经常去想,就会比别人想的深刻,周全。
 
对一件事情想象得深刻,并不是靠聪明就可以做得来的。
 
独立的时间,空间,不干扰。

别忘了问题,天天想,想得比别人多,足够多。
收起阅读 »

Ptrade策略示例

策略示例
 
集合竞价追涨停策略
def initialize(context):
# 初始化此策略
# 设置我们要操作的股票池, 这里我们只操作一支股票
g.security = '600570.SS'
set_universe(g.security)
#每天9:23分运行集合竞价处理函数
run_daily(context, aggregate_auction_func, time='9:23')

def aggregate_auction_func(context):
stock = g.security
#最新价
snapshot = get_snapshot(stock)
price = snapshot[stock]['last_px']
#涨停价
up_limit = snapshot[stock]['up_px']
#如果最新价不小于涨停价,买入
if float(price) >= float(up_limit):
order(g.security, 100, limit_price=up_limit)

def handle_data(context, data):
pass

tick级别均线策略
def initialize(context):
# 初始化此策略
# 设置我们要操作的股票池, 这里我们只操作一支股票
g.security = '600570.SS'
set_universe(g.security)
#每3秒运行一次主函数
run_interval(context, func, seconds=3)

#盘前准备历史数据
def before_trading_start(context, data):
history = get_history(10, '1d', 'close', g.security, fq='pre', include=False)
g.close_array = history['close'].values

#当五日均线高于十日均线时买入,当五日均线低于十日均线时卖出
def func(context):

stock = g.security

#获取最新价
snapshot = get_snapshot(stock)
price = snapshot[stock]['last_px']

# 得到五日均线价格
days = 5
ma5 = get_MA_day(stock, days, g.close_array[-4:], price)
# 得到十日均线价格
days = 10
ma10 = get_MA_day(stock, days, g.close_array[-9:], price)

# 得到当前资金余额
cash = context.portfolio.cash

# 如果当前有余额,并且五日均线大于十日均线
if ma5 > ma10:
# 用所有 cash 买入股票
order_value(stock, cash)
# 记录这次买入
log.info("Buying %s" % (stock))

# 如果五日均线小于十日均线,并且目前有头寸
elif ma5 < ma10 and get_position(stock).amount > 0:
# 全部卖出
order_target(stock, 0)
# 记录这次卖出
log.info("Selling %s" % (stock))

#计算实时均线函数
def get_MA_day(stock,days,close_array,current_price):
close_sum = close_array[-(days-1):].sum()
MA = (current_price + close_sum)/days
return MA

def handle_data(context, data):
pass

双均线策略
def initialize(context):
# 初始化此策略
# 设置我们要操作的股票池, 这里我们只操作一支股票
g.security = '600570.SS'
set_universe(g.security)
pass

#当五日均线高于十日均线时买入,当五日均线低于十日均线时卖出
def handle_data(context, data):
security = g.security

#得到十日历史价格
df = get_history(10, '1d', 'close', security, fq=None, include=False)

# 得到五日均线价格
ma5 = round(df['close'][-5:].mean(), 3)

# 得到十日均线价格
ma10 = round(df['close'][-10:].mean(), 3)

# 取得昨天收盘价
price = data[security]['close']

# 得到当前资金余额
cash = context.portfolio.cash

# 如果当前有余额,并且五日均线大于十日均线
if ma5 > ma10:
# 用所有 cash 买入股票
order_value(security, cash)
# 记录这次买入
log.info("Buying %s" % (security))

# 如果五日均线小于十日均线,并且目前有头寸
elif ma5 < ma10 and get_position(security).amount > 0:
# 全部卖出
order_target(security, 0)
# 记录这次卖出
log.info("Selling %s" % (security))

 macd策略

指数平滑均线函数,以price计算,可以选择收盘、开盘价等价格,N为时间周期,m用于计算平滑系数a=m/(N+1),EXPMA1为前一日值
def f_expma(N,m,EXPMA1,price):
a = m/(N+1)
EXPMA2 = a * price + (1 - a)*EXPMA1
return EXPMA2 #2为后一天值

#定义macd函数,输入平滑系数参数、前一日值,输出当日值
def macd(N1,N2,N3,m,EXPMA12_1,EXPMA26_1,DEA1,price):
EXPMA12_2 = f_expma(N1,m,EXPMA12_1,price)
EXPMA26_2 = f_expma(N2,m,EXPMA26_1,price)
DIF2 = EXPMA12_2 - EXPMA26_2
a = m/(N3+1)
DEA2 = a * DIF2 + (1 - a)*DEA1
BAR2=2*(DIF2-DEA2)
return EXPMA12_2,EXPMA26_2,DIF2,DEA2,BAR2

def initialize(context):
global init_price
init_price = None
# 获取沪深300股票
g.security = get_index_stocks('000300.SS')
#g.security = ['600570.SS']
# 设置我们要操作的股票池, 这里我们只操作一支股票
set_universe(g.security)

def handle_data(context, data):
# 获取历史数据,这里只获取了2天的数据,如果希望最终MACD指标结果更准确最好是获取
# 从股票上市至今的所有历史数据,即增加获取的天数
close_price = get_history(2, '1d', field='close', security_list=g.security)
#如果是停牌不进行计算
for security in g.security:
if data[security].is_open >0:
global init_price,EXPMA12_1,EXPMA26_1,EXPMA12_2,EXPMA26_2,DIF1,DIF2,DEA1,DEA2
if init_price is None:
init_price = close_price[security].mean()#nan和N-1个数,mean为N-1个数的均值
EXPMA12_1 = init_price
EXPMA26_1 = init_price
DIF1 = init_price
DEA1 = init_price
# m用于计算平滑系数a=m/(N+1)
m = 2.0
#设定指数平滑基期数
N1 = 12
N2 = 26
N3 = 9
EXPMA12_2,EXPMA26_2,DIF2,DEA2,BAR2 = macd(N1,N2,N3,m,EXPMA12_1,EXPMA26_1,DEA1,close_price[security][-1])
# 取得当前价格
current_price = data[security].price
# 取得当前的现金
cash = context.portfolio.cash
# DIF、DEA均为正,DIF向上突破DEA,买入信号参考
if DIF2 > 0 and DEA2 > 0 and DIF1 < DEA1 and DIF2 > DEA2:
# 计算可以买多少只股票
number_of_shares = int(cash/current_price)
# 购买量大于0时,下单
if number_of_shares > 0:
# 以市单价买入股票,日回测时即是开盘价
order(security, +number_of_shares)
# 记录这次买入
log.info("Buying %s" % (security))
# DIF、DEA均为负,DIF向下突破DEA,卖出信号参考
elif DIF2 < 0 and DEA2 < 0 and DIF1 > DEA1 and DIF2 < DEA2 and get_position(security).amount > 0:
# 卖出所有股票,使这只股票的最终持有量为0
order_target(security, 0)
# 记录这次卖出
log.info("Selling %s" % (security))
# 将今日的值赋给全局变量作为下一次前一日的值
DEA1 = DEA2
DIF1 = DIF2
EXPMA12_1 = EXPMA12_2
EXPMA26_1 = EXPMA26_2

如果需要开通Ptrade量化接口,只需资金50W存放一周即可。
交易费率也很便宜,股票万一,基金万0.6, 可转债百万分之二。
量化接口不需要收取任何费用。
有意者可以扫码开户:
继续阅读 »
策略示例
 
集合竞价追涨停策略
def initialize(context):
# 初始化此策略
# 设置我们要操作的股票池, 这里我们只操作一支股票
g.security = '600570.SS'
set_universe(g.security)
#每天9:23分运行集合竞价处理函数
run_daily(context, aggregate_auction_func, time='9:23')

def aggregate_auction_func(context):
stock = g.security
#最新价
snapshot = get_snapshot(stock)
price = snapshot[stock]['last_px']
#涨停价
up_limit = snapshot[stock]['up_px']
#如果最新价不小于涨停价,买入
if float(price) >= float(up_limit):
order(g.security, 100, limit_price=up_limit)

def handle_data(context, data):
pass

tick级别均线策略
def initialize(context):
# 初始化此策略
# 设置我们要操作的股票池, 这里我们只操作一支股票
g.security = '600570.SS'
set_universe(g.security)
#每3秒运行一次主函数
run_interval(context, func, seconds=3)

#盘前准备历史数据
def before_trading_start(context, data):
history = get_history(10, '1d', 'close', g.security, fq='pre', include=False)
g.close_array = history['close'].values

#当五日均线高于十日均线时买入,当五日均线低于十日均线时卖出
def func(context):

stock = g.security

#获取最新价
snapshot = get_snapshot(stock)
price = snapshot[stock]['last_px']

# 得到五日均线价格
days = 5
ma5 = get_MA_day(stock, days, g.close_array[-4:], price)
# 得到十日均线价格
days = 10
ma10 = get_MA_day(stock, days, g.close_array[-9:], price)

# 得到当前资金余额
cash = context.portfolio.cash

# 如果当前有余额,并且五日均线大于十日均线
if ma5 > ma10:
# 用所有 cash 买入股票
order_value(stock, cash)
# 记录这次买入
log.info("Buying %s" % (stock))

# 如果五日均线小于十日均线,并且目前有头寸
elif ma5 < ma10 and get_position(stock).amount > 0:
# 全部卖出
order_target(stock, 0)
# 记录这次卖出
log.info("Selling %s" % (stock))

#计算实时均线函数
def get_MA_day(stock,days,close_array,current_price):
close_sum = close_array[-(days-1):].sum()
MA = (current_price + close_sum)/days
return MA

def handle_data(context, data):
pass

双均线策略
def initialize(context):
# 初始化此策略
# 设置我们要操作的股票池, 这里我们只操作一支股票
g.security = '600570.SS'
set_universe(g.security)
pass

#当五日均线高于十日均线时买入,当五日均线低于十日均线时卖出
def handle_data(context, data):
security = g.security

#得到十日历史价格
df = get_history(10, '1d', 'close', security, fq=None, include=False)

# 得到五日均线价格
ma5 = round(df['close'][-5:].mean(), 3)

# 得到十日均线价格
ma10 = round(df['close'][-10:].mean(), 3)

# 取得昨天收盘价
price = data[security]['close']

# 得到当前资金余额
cash = context.portfolio.cash

# 如果当前有余额,并且五日均线大于十日均线
if ma5 > ma10:
# 用所有 cash 买入股票
order_value(security, cash)
# 记录这次买入
log.info("Buying %s" % (security))

# 如果五日均线小于十日均线,并且目前有头寸
elif ma5 < ma10 and get_position(security).amount > 0:
# 全部卖出
order_target(security, 0)
# 记录这次卖出
log.info("Selling %s" % (security))

 macd策略

指数平滑均线函数,以price计算,可以选择收盘、开盘价等价格,N为时间周期,m用于计算平滑系数a=m/(N+1),EXPMA1为前一日值
def f_expma(N,m,EXPMA1,price):
a = m/(N+1)
EXPMA2 = a * price + (1 - a)*EXPMA1
return EXPMA2 #2为后一天值

#定义macd函数,输入平滑系数参数、前一日值,输出当日值
def macd(N1,N2,N3,m,EXPMA12_1,EXPMA26_1,DEA1,price):
EXPMA12_2 = f_expma(N1,m,EXPMA12_1,price)
EXPMA26_2 = f_expma(N2,m,EXPMA26_1,price)
DIF2 = EXPMA12_2 - EXPMA26_2
a = m/(N3+1)
DEA2 = a * DIF2 + (1 - a)*DEA1
BAR2=2*(DIF2-DEA2)
return EXPMA12_2,EXPMA26_2,DIF2,DEA2,BAR2

def initialize(context):
global init_price
init_price = None
# 获取沪深300股票
g.security = get_index_stocks('000300.SS')
#g.security = ['600570.SS']
# 设置我们要操作的股票池, 这里我们只操作一支股票
set_universe(g.security)

def handle_data(context, data):
# 获取历史数据,这里只获取了2天的数据,如果希望最终MACD指标结果更准确最好是获取
# 从股票上市至今的所有历史数据,即增加获取的天数
close_price = get_history(2, '1d', field='close', security_list=g.security)
#如果是停牌不进行计算
for security in g.security:
if data[security].is_open >0:
global init_price,EXPMA12_1,EXPMA26_1,EXPMA12_2,EXPMA26_2,DIF1,DIF2,DEA1,DEA2
if init_price is None:
init_price = close_price[security].mean()#nan和N-1个数,mean为N-1个数的均值
EXPMA12_1 = init_price
EXPMA26_1 = init_price
DIF1 = init_price
DEA1 = init_price
# m用于计算平滑系数a=m/(N+1)
m = 2.0
#设定指数平滑基期数
N1 = 12
N2 = 26
N3 = 9
EXPMA12_2,EXPMA26_2,DIF2,DEA2,BAR2 = macd(N1,N2,N3,m,EXPMA12_1,EXPMA26_1,DEA1,close_price[security][-1])
# 取得当前价格
current_price = data[security].price
# 取得当前的现金
cash = context.portfolio.cash
# DIF、DEA均为正,DIF向上突破DEA,买入信号参考
if DIF2 > 0 and DEA2 > 0 and DIF1 < DEA1 and DIF2 > DEA2:
# 计算可以买多少只股票
number_of_shares = int(cash/current_price)
# 购买量大于0时,下单
if number_of_shares > 0:
# 以市单价买入股票,日回测时即是开盘价
order(security, +number_of_shares)
# 记录这次买入
log.info("Buying %s" % (security))
# DIF、DEA均为负,DIF向下突破DEA,卖出信号参考
elif DIF2 < 0 and DEA2 < 0 and DIF1 > DEA1 and DIF2 < DEA2 and get_position(security).amount > 0:
# 卖出所有股票,使这只股票的最终持有量为0
order_target(security, 0)
# 记录这次卖出
log.info("Selling %s" % (security))
# 将今日的值赋给全局变量作为下一次前一日的值
DEA1 = DEA2
DIF1 = DIF2
EXPMA12_1 = EXPMA12_2
EXPMA26_1 = EXPMA26_2

如果需要开通Ptrade量化接口,只需资金50W存放一周即可。
交易费率也很便宜,股票万一,基金万0.6, 可转债百万分之二。
量化接口不需要收取任何费用。
有意者可以扫码开户:
收起阅读 »

股票量化接口 支持python 费率低 股票万一 免五

基于恒生电子的Ptrade系统。
可以使用可视化创建策略进行自动交易,内置的量化策略有打板策略,追涨策略,ETF申购套利策略,可转债套利策略,期现套利策略,等等,太多了,就挑几个写出了。

kTmn9iOXaS.png

 
而更为高级的功能则通过python编程自动化交易程序:

Pig1iRRQnP.png

 

25YjBEdOqa.png

 

Hc8f4UtMfW.png

 
提供了完善的使用文档:

uQ8yuFUOqj.png

 
 
开通条件只需要30W资金存放约1周即可。

具体交易费率是股票万1棉吾,可转债沪深十万分之五,基金万0.6
 
需要的可以扫码开户:

股票费率是万一免五【开通量化API接口后】
继续阅读 »
基于恒生电子的Ptrade系统。
可以使用可视化创建策略进行自动交易,内置的量化策略有打板策略,追涨策略,ETF申购套利策略,可转债套利策略,期现套利策略,等等,太多了,就挑几个写出了。

kTmn9iOXaS.png

 
而更为高级的功能则通过python编程自动化交易程序:

Pig1iRRQnP.png

 

25YjBEdOqa.png

 

Hc8f4UtMfW.png

 
提供了完善的使用文档:

uQ8yuFUOqj.png

 
 
开通条件只需要30W资金存放约1周即可。

具体交易费率是股票万1棉吾,可转债沪深十万分之五,基金万0.6
 
需要的可以扫码开户:

股票费率是万一免五【开通量化API接口后】 收起阅读 »

国金证券万一 免5开户 还有吗?

### 2022-08-29 更新 #############
目前国金可以万一免五开户开户啦
 ### 2022-05-29 更新 #############
 
目前国金 佣金宝 开户费率可调至股票万一,资金达标者可以万一,具体标准可以联系文末的微信。
 
国金之前是腾讯京东入股的券商,主要在网上开户渠道较多,线下营业部貌似比较少,不过大部分业务可以在app就可以完成的了。
 
一般官网开的费率都是万2.5。(小白用户)


有意开户者可以扫描下面二维码:



备注:开户

目前国金费率是万1,很划算的。 
市场上也很难找到万一免五的国金,机会难得,要珍惜,机会就像 过去的船,射出去的箭,不好好把握,就很难等下一次了。
 

注:
超过3个户的可以只开通深圳的证券户,上海的可以转过来或者后面慢慢销掉不常用的。
 
继续阅读 »
### 2022-08-29 更新 #############
目前国金可以万一免五开户开户啦
 ### 2022-05-29 更新 #############
 
目前国金 佣金宝 开户费率可调至股票万一,资金达标者可以万一,具体标准可以联系文末的微信。
 
国金之前是腾讯京东入股的券商,主要在网上开户渠道较多,线下营业部貌似比较少,不过大部分业务可以在app就可以完成的了。
 
一般官网开的费率都是万2.5。(小白用户)


有意开户者可以扫描下面二维码:



备注:开户

目前国金费率是万1,很划算的。 
市场上也很难找到万一免五的国金,机会难得,要珍惜,机会就像 过去的船,射出去的箭,不好好把握,就很难等下一次了。
 

注:
超过3个户的可以只开通深圳的证券户,上海的可以转过来或者后面慢慢销掉不常用的。
  收起阅读 »

中国互联套利教程 手摸手操作教程

整体流程如下:先挖坑,后续逐渐填
 1. 首先发现溢价的基金
 
2. 查看公告
 
3. 准备一个基金申购费率低的券商账号
 
4. 申购
 
5. 等待到账,卖出
 
6. 结束
整体流程如下:先挖坑,后续逐渐填
 1. 首先发现溢价的基金
 
2. 查看公告
 
3. 准备一个基金申购费率低的券商账号
 
4. 申购
 
5. 等待到账,卖出
 
6. 结束

中国互联申购到账 还好有申购一折

中国互联溢价申购套利记录:
 上周四开始套的

Screenshot_2021_0524_233424.jpg

 
单个股东户申购5000,实际申购份额2693份,成交金额: 4944,到账4938,手续费5.93,在百分之1.5的基础上打了一折,实际算下来,费率0.12%。
 
目前一个股东户持有市值:5060,一个户净赚:5060-4944 = 115,一个稍微豪华点的盒饭钱。
不过明天肯定是低开的了。
 
如果需要银河开户,有基金申购打折,并且股票万一免五,
可以扫码联系:

非诚勿扰,备注:开户
继续阅读 »
中国互联溢价申购套利记录:
 上周四开始套的

Screenshot_2021_0524_233424.jpg

 
单个股东户申购5000,实际申购份额2693份,成交金额: 4944,到账4938,手续费5.93,在百分之1.5的基础上打了一折,实际算下来,费率0.12%。
 
目前一个股东户持有市值:5060,一个户净赚:5060-4944 = 115,一个稍微豪华点的盒饭钱。
不过明天肯定是低开的了。
 
如果需要银河开户,有基金申购打折,并且股票万一免五,
可以扫码联系:

非诚勿扰,备注:开户 收起阅读 »

银河证券的缺点

就是经常晚上提示说券商测试,数据显示不准确,导致不给登录。 怎么一个晚上都在测试呢?
明显是直接关停了,免得别人在操作干坏事。
就是经常晚上提示说券商测试,数据显示不准确,导致不给登录。 怎么一个晚上都在测试呢?
明显是直接关停了,免得别人在操作干坏事。

火币登录时提示 谷歌验证码错误 无法登录

安全器使用的时谷歌身份验证器,反复登录几次后一直提示谷歌验证码错误,,请重新输入。
难度凉凉了吗??
和客服聊了下,只好解绑。或者用app登录
安全器使用的时谷歌身份验证器,反复登录几次后一直提示谷歌验证码错误,,请重新输入。
难度凉凉了吗??
和客服聊了下,只好解绑。或者用app登录

韦世东 python3网络爬虫宝典 勘误

P231:
1. 时间差是正数才是过期
2. 获取权限那里,permission = args[0].permission
不能后面再用get
 
P222:
写入mongodb后,原来的数据会被加入一个_id,值为OjectId,该值是无法被json dumps为string,
所以需要手工把ObjectId 转为str,或者del message['_id'] 将这个键去除。
 

 
继续阅读 »
P231:
1. 时间差是正数才是过期
2. 获取权限那里,permission = args[0].permission
不能后面再用get
 
P222:
写入mongodb后,原来的数据会被加入一个_id,值为OjectId,该值是无法被json dumps为string,
所以需要手工把ObjectId 转为str,或者del message['_id'] 将这个键去除。
 

  收起阅读 »

贝壳左晖一生的评价?

本人不算有钱,总共出手过三套房产,

成都市的。

成都去年年底到今年的二手房大涨,

明显是资本在推

贝壳就是其中很大的推手。

我在去年12月给贝壳打电话,

告诉他们我有房子要出手,

当时小区的成交价格大概是230万上下。

我跟中介说明情况以后,他问我着不着急卖,

我问他什么意思。

他告诉我可以挂高价,

建议我挂个255,说是有议价空间。

后面我才明白过来,搁这儿玩滚动出货呢。

诚心卖急用钱的房东,中介会压低他们的价格,

促进成交。

而我这样的,就给人当绿叶,掩护低价房源出手。

实际上就是贝壳和部分房东联手做局,

抬高价格,买家有些是刚需,只能硬着头皮上。

某朋友系列。
 
这是某位朋友的体会。
 
然后知乎,雪球上一些大佬为左晖洗白。尤其雪球的方丈,以为自己说的都是正义的。
 
 这典型的屁股决定脑袋,说现在的年轻人戾气很重,哎。
如果这些大佬想想,现在的90后,996工作,然后蜗居在自如的甲醛房子里面,然后月底收到自如的涨价通知。
看着高企的房价,人生似乎也没什么盼头。
然后网上键盘侠一下哎,也不行呀,他们也挺难的。
 
 
继续阅读 »
本人不算有钱,总共出手过三套房产,

成都市的。

成都去年年底到今年的二手房大涨,

明显是资本在推

贝壳就是其中很大的推手。

我在去年12月给贝壳打电话,

告诉他们我有房子要出手,

当时小区的成交价格大概是230万上下。

我跟中介说明情况以后,他问我着不着急卖,

我问他什么意思。

他告诉我可以挂高价,

建议我挂个255,说是有议价空间。

后面我才明白过来,搁这儿玩滚动出货呢。

诚心卖急用钱的房东,中介会压低他们的价格,

促进成交。

而我这样的,就给人当绿叶,掩护低价房源出手。

实际上就是贝壳和部分房东联手做局,

抬高价格,买家有些是刚需,只能硬着头皮上。

某朋友系列。
 
这是某位朋友的体会。
 
然后知乎,雪球上一些大佬为左晖洗白。尤其雪球的方丈,以为自己说的都是正义的。
 
 这典型的屁股决定脑袋,说现在的年轻人戾气很重,哎。
如果这些大佬想想,现在的90后,996工作,然后蜗居在自如的甲醛房子里面,然后月底收到自如的涨价通知。
看着高企的房价,人生似乎也没什么盼头。
然后网上键盘侠一下哎,也不行呀,他们也挺难的。
 
  收起阅读 »

折腾了半天,结果发现windows上无法使用redis 布隆过滤器插件

运行实例代码:

# Using Bloom Filter from redisbloom.client import Client rb = Client() rb.bfCreate('bloom', 0.01, 1000) rb.bfAdd('bloom', 'foo') # returns 1 rb.bfAdd('bloom', 'foo') # returns 0 rb.bfExists('bloom', 'foo') # returns 1 rb.bfExists('bloom', 'noexist') # returns 0
 
 
报错:
redis.exceptions.ResponseError: unknown command BF.RESERVE, with args beginning with: bloom, 0.01, 1000 
 连docker上得镜像也不支持。
更别说windows版本上的redis按照插件了。
 
只好用linux的docker了。

docker run -p 6379:6379 --name redis-redisbloom redislabs/rebloom:latest

 
继续阅读 »
运行实例代码:

# Using Bloom Filter from redisbloom.client import Client rb = Client() rb.bfCreate('bloom', 0.01, 1000) rb.bfAdd('bloom', 'foo') # returns 1 rb.bfAdd('bloom', 'foo') # returns 0 rb.bfExists('bloom', 'foo') # returns 1 rb.bfExists('bloom', 'noexist') # returns 0
 
 
报错:
redis.exceptions.ResponseError: unknown command BF.RESERVE, with args beginning with: bloom, 0.01, 1000 
 连docker上得镜像也不支持。
更别说windows版本上的redis按照插件了。
 
只好用linux的docker了。

docker run -p 6379:6379 --name redis-redisbloom redislabs/rebloom:latest

  收起阅读 »

PI币邀请码:yagamizsu

输入邀请码才能继续注册哦
邀请码:yagamizsu
用邀请码注册后会获得几个PI币。
输入邀请码才能继续注册哦
邀请码:yagamizsu
用邀请码注册后会获得几个PI币。

coinegg.fun coinegg币蛋真垃圾 入金最低要10000


urtsGfHmox.png


 点击查看大图

请在10000-1000000之间设置金额。。。
 这样子玩,迟早没有人气的了。韭菜都去了隔壁火币平台了。
 

urtsGfHmox.png


 点击查看大图

请在10000-1000000之间设置金额。。。
 这样子玩,迟早没有人气的了。韭菜都去了隔壁火币平台了。
 

火币邀请码:9dsub

或者点击链接开户:https://www.huobi.pe/zh-cn/topic/invited/?invite_code=9dsub
最近行情火爆,可以进场捞一笔就走。
 
注意,所有币都是空气,进去的人都是赌徒。如果你觉得你赌术高明,那么你就可以试试。
 
火币邀请码:9dsub
 
火币邀请码有什么用?
对于新用户,没什么用的。而对于邀请别人的人,可以获取200个火苗,说实话,这个玩意我也不知道有啥用。
 
官方的奖励:
1、好友接受邀请后,每产生一笔真实交易手续费,会产生相应比例的奖励。

2、奖励的形式以USDT或点卡或HT的形式发放到您的交易账户,USDT奖励比例为30%,点卡奖励比例为30%,HT奖励比例为30%。

3、被邀请人使用点卡交易时,邀请人实际获得的奖励将以等额的点数进行计算后发给邀请人;被邀请人使用非点卡交易且手续费为HT时,邀请人实际获得的奖励将以HT进行计算后发给邀请人;被邀请人使用非点卡交易且手续费不为HT时,邀请人实际获得的奖励将以USDT进行折合计算后发给邀请人。

4、好友交易奖励当日统计,次日晚到账;奖励额(USDT或点卡或HT)= 实际产生交易量 * 手续费比例*奖励比例。

5、邀请人享受好友交易返佣有效时长以被邀请人实际注册的时间开始进行计算,到达有效时长(730天)后您将不享受该邀请人交易产生手续费的返佣。

6、平台将以每5分钟取一次市价进行相应币种的USDT实时换算,奖励金额以实际奖励金额为准。

7、每月1号月度榜单只可以看到上月数据。

8、每日结算时间为:0:00;打款时间为次日晚十点前。

9、充提币手续费,杠杆利息不参与手续费奖励。

10、如被邀请人违反邀请奖励的相应风控规则,其手续费将不能发放给邀请人,同时,被邀请人的邀请状态变成【已无效】并且产生的奖励记录状态变成【奖励无效】。

11、单一被邀请人奖励上限为5000USDT(点卡价值与USDT锚定1:1,HT按交易时市价折合USDT),无被邀请人数量上限。

12、如有深度渠道合作意向,请联系app@huobi.com,邮件需包含火币UID、展业国家和地区、自有资源背景、简要展业计划、自我介绍、个人微信或手机号等信息。

活动如有调整,以火币全球站平台更新为准,最终解释权归火币全球站所有。
 
继续阅读 »
或者点击链接开户:https://www.huobi.pe/zh-cn/topic/invited/?invite_code=9dsub
最近行情火爆,可以进场捞一笔就走。
 
注意,所有币都是空气,进去的人都是赌徒。如果你觉得你赌术高明,那么你就可以试试。
 
火币邀请码:9dsub
 
火币邀请码有什么用?
对于新用户,没什么用的。而对于邀请别人的人,可以获取200个火苗,说实话,这个玩意我也不知道有啥用。
 
官方的奖励:
1、好友接受邀请后,每产生一笔真实交易手续费,会产生相应比例的奖励。

2、奖励的形式以USDT或点卡或HT的形式发放到您的交易账户,USDT奖励比例为30%,点卡奖励比例为30%,HT奖励比例为30%。

3、被邀请人使用点卡交易时,邀请人实际获得的奖励将以等额的点数进行计算后发给邀请人;被邀请人使用非点卡交易且手续费为HT时,邀请人实际获得的奖励将以HT进行计算后发给邀请人;被邀请人使用非点卡交易且手续费不为HT时,邀请人实际获得的奖励将以USDT进行折合计算后发给邀请人。

4、好友交易奖励当日统计,次日晚到账;奖励额(USDT或点卡或HT)= 实际产生交易量 * 手续费比例*奖励比例。

5、邀请人享受好友交易返佣有效时长以被邀请人实际注册的时间开始进行计算,到达有效时长(730天)后您将不享受该邀请人交易产生手续费的返佣。

6、平台将以每5分钟取一次市价进行相应币种的USDT实时换算,奖励金额以实际奖励金额为准。

7、每月1号月度榜单只可以看到上月数据。

8、每日结算时间为:0:00;打款时间为次日晚十点前。

9、充提币手续费,杠杆利息不参与手续费奖励。

10、如被邀请人违反邀请奖励的相应风控规则,其手续费将不能发放给邀请人,同时,被邀请人的邀请状态变成【已无效】并且产生的奖励记录状态变成【奖励无效】。

11、单一被邀请人奖励上限为5000USDT(点卡价值与USDT锚定1:1,HT按交易时市价折合USDT),无被邀请人数量上限。

12、如有深度渠道合作意向,请联系app@huobi.com,邮件需包含火币UID、展业国家和地区、自有资源背景、简要展业计划、自我介绍、个人微信或手机号等信息。

活动如有调整,以火币全球站平台更新为准,最终解释权归火币全球站所有。
  收起阅读 »

pyautogui无法再远程桌面最小化或者断线后进行截图

搜索了一圈,似乎无解。
知道的朋友可以私信下我。
 
国外的论坛也找不到答案,只能一直开着屏幕了。。。。
搜索了一圈,似乎无解。
知道的朋友可以私信下我。
 
国外的论坛也找不到答案,只能一直开着屏幕了。。。。

pyppeteer 在AppData下的dev_profile 生成大量文件

具体路径在:
C:\Users\xda\AppData\Local\pyppeteer\pyppeteer\.dev_profile
运行次数多了,这个目录下积累了几十个G的文件。
 

DV0VxpbNtN.png

 
因为每次启动pyppeteer后,如果不指定userData目录,会在dev_profile生成一个新的userData目录,每次大概30MB左右的打小,所以启动的次数,越多,这个文件夹的体积就越大。
其实可以直接删除,然后启动pyppeteer是加上一个参数:userDataDir
    browser = await pyppeteer.launch(
{'headless': False,
'userDataDir': UserDataDir,
'defaultViewport': {'width': 1800, 'height': 1000},
# 'enable-automation':False,
# 'ignoreDefaultArgs':['--enable-automation'],
'ignoreDefaultArgs':True,
}
userDataDir='D:\Temp'
这样每次pyppeteer都会用同一个配置文件,并且还可以把cookies,session文件存在同一个地方,如果登录过的网站,下次可以直接登录,不需要再次输入账号密码。
 
 
继续阅读 »
具体路径在:
C:\Users\xda\AppData\Local\pyppeteer\pyppeteer\.dev_profile
运行次数多了,这个目录下积累了几十个G的文件。
 

DV0VxpbNtN.png

 
因为每次启动pyppeteer后,如果不指定userData目录,会在dev_profile生成一个新的userData目录,每次大概30MB左右的打小,所以启动的次数,越多,这个文件夹的体积就越大。
其实可以直接删除,然后启动pyppeteer是加上一个参数:userDataDir
    browser = await pyppeteer.launch(
{'headless': False,
'userDataDir': UserDataDir,
'defaultViewport': {'width': 1800, 'height': 1000},
# 'enable-automation':False,
# 'ignoreDefaultArgs':['--enable-automation'],
'ignoreDefaultArgs':True,
}
userDataDir='D:\Temp'
这样每次pyppeteer都会用同一个配置文件,并且还可以把cookies,session文件存在同一个地方,如果登录过的网站,下次可以直接登录,不需要再次输入账号密码。
 
  收起阅读 »

哪些证券开户可以免5

笔者手头有2家券商可以免五开户,股票费率万分之一,免五,没有最低,买多少算多少,比如买1千块就只收1毛钱。
 


转债,基金ETF这些也都是免五。支持同花顺,支持条件单。并且基金申购有一折
 
 
需要的朋友可以联系下方二维码开户: 备注:开户, 不然会不通过哦
继续阅读 »
笔者手头有2家券商可以免五开户,股票费率万分之一,免五,没有最低,买多少算多少,比如买1千块就只收1毛钱。
 


转债,基金ETF这些也都是免五。支持同花顺,支持条件单。并且基金申购有一折
 
 
需要的朋友可以联系下方二维码开户: 备注:开户, 不然会不通过哦
收起阅读 »

pip install peewee : AttributeError: 'str' object has no attribute 'decode'

 
    ERROR: Command errored out with exit status 1:
command: 'C:\anaconda\python.exe' -c 'import sys, setuptools, tokenize; sys.argv[0] = '"'"'C:\\Users\\xda\\AppData\
\Local\\Temp\\pip-install-ftotbzih\\peewee\\setup.py'"'"'; __file__='"'"'C:\\Users\\xda\\AppData\\Local\\Temp\\pip-insta
ll-ftotbzih\\peewee\\setup.py'"'"';f=getattr(tokenize, '"'"'open'"'"', open)(__file__);code=f.read().replace('"'"'\r\n'"
'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' egg_info --egg-base 'C:\Users\xda\AppData\Lo
cal\Temp\pip-pip-egg-info-8ou7yi3i'
cwd: C:\Users\xda\AppData\Local\Temp\pip-install-ftotbzih\peewee\
Complete output (15 lines):
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "C:\Users\xda\AppData\Local\Temp\pip-install-ftotbzih\peewee\setup.py", line 99, in <module>
elif not _have_sqlite_extension_support():
File "C:\Users\xda\AppData\Local\Temp\pip-install-ftotbzih\peewee\setup.py", line 76, in _have_sqlite_extension_su
pport
compiler.compile([src_file], output_dir=tmp_dir),
File "C:\anaconda\lib\distutils\_msvccompiler.py", line 327, in compile
self.initialize()
File "C:\anaconda\lib\distutils\_msvccompiler.py", line 224, in initialize
vc_env = _get_vc_env(plat_spec)
File "C:\anaconda\lib\site-packages\setuptools\msvc.py", line 314, in msvc14_get_vc_env
return _msvc14_get_vc_env(plat_spec)
File "C:\anaconda\lib\site-packages\setuptools\msvc.py", line 273, in _msvc14_get_vc_env
out = subprocess.check_output(
AttributeError: 'str' object has no attribute 'decode'
----------------------------------------
ERROR: Command errored out with exit status 1: python setup.py egg_info Check the logs for full command output.

同样的编码问题,同样的解决方法:
找到文件msvc.py
大概在276行:
        out = subprocess.check_output(
'cmd /u /c "{}" {} && set'.format(vcvarsall, plat_spec),
stderr=subprocess.STDOUT,
)
# ).decode('utf-16le', errors='replace')
把decode的部分注释掉即可
 
继续阅读 »
 
    ERROR: Command errored out with exit status 1:
command: 'C:\anaconda\python.exe' -c 'import sys, setuptools, tokenize; sys.argv[0] = '"'"'C:\\Users\\xda\\AppData\
\Local\\Temp\\pip-install-ftotbzih\\peewee\\setup.py'"'"'; __file__='"'"'C:\\Users\\xda\\AppData\\Local\\Temp\\pip-insta
ll-ftotbzih\\peewee\\setup.py'"'"';f=getattr(tokenize, '"'"'open'"'"', open)(__file__);code=f.read().replace('"'"'\r\n'"
'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' egg_info --egg-base 'C:\Users\xda\AppData\Lo
cal\Temp\pip-pip-egg-info-8ou7yi3i'
cwd: C:\Users\xda\AppData\Local\Temp\pip-install-ftotbzih\peewee\
Complete output (15 lines):
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "C:\Users\xda\AppData\Local\Temp\pip-install-ftotbzih\peewee\setup.py", line 99, in <module>
elif not _have_sqlite_extension_support():
File "C:\Users\xda\AppData\Local\Temp\pip-install-ftotbzih\peewee\setup.py", line 76, in _have_sqlite_extension_su
pport
compiler.compile([src_file], output_dir=tmp_dir),
File "C:\anaconda\lib\distutils\_msvccompiler.py", line 327, in compile
self.initialize()
File "C:\anaconda\lib\distutils\_msvccompiler.py", line 224, in initialize
vc_env = _get_vc_env(plat_spec)
File "C:\anaconda\lib\site-packages\setuptools\msvc.py", line 314, in msvc14_get_vc_env
return _msvc14_get_vc_env(plat_spec)
File "C:\anaconda\lib\site-packages\setuptools\msvc.py", line 273, in _msvc14_get_vc_env
out = subprocess.check_output(
AttributeError: 'str' object has no attribute 'decode'
----------------------------------------
ERROR: Command errored out with exit status 1: python setup.py egg_info Check the logs for full command output.

同样的编码问题,同样的解决方法:
找到文件msvc.py
大概在276行:
        out = subprocess.check_output(
'cmd /u /c "{}" {} && set'.format(vcvarsall, plat_spec),
stderr=subprocess.STDOUT,
)
# ).decode('utf-16le', errors='replace')
把decode的部分注释掉即可
  收起阅读 »

招商证券可以办万一免5吗

最近不少读者朋友咨询 招商证券的万一免五开户。
刚好最近有有个招商证券的营业部可以提供这个费率(万一免五),因为本身对大券商而言,万一的费率已经很难的了,况且还可以免5。
 
不过招商证券的免五需要一定的入金条件,并且可以有不同的档位,有万1.5免五,万1.2免五,万1免五
 

如果需要的,可以扫描一下二维码咨询开户。
另外还有其他多个券商可供选择,大小券商都有,费率保证同行最低,任君选择。
 


请备注开户,非诚无扰。
 


 
继续阅读 »
最近不少读者朋友咨询 招商证券的万一免五开户。
刚好最近有有个招商证券的营业部可以提供这个费率(万一免五),因为本身对大券商而言,万一的费率已经很难的了,况且还可以免5。
 
不过招商证券的免五需要一定的入金条件,并且可以有不同的档位,有万1.5免五,万1.2免五,万1免五
 

如果需要的,可以扫描一下二维码咨询开户。
另外还有其他多个券商可供选择,大小券商都有,费率保证同行最低,任君选择。
 


请备注开户,非诚无扰。
 


  收起阅读 »

特斯拉水军还挺多的 还是友商的高级黑呢

天天上头条,然后评论里第一点赞最多的
独家对话上海维权女车主:请特斯拉到事发路段实地测速
 

e0ZOIQF3lK.png


duhN7PanRb.png

 
这么明显的水军,会不会是友商一起黑呢
毕竟国内的电车厂商背后的财团应该比特斯拉大得多。纯粹猜测。
反正对特斯拉没有好感,这个明显是软件设计的bug。
很早前就有了。 只是一只就没改过来。
刹车时系统回收电力,系统来减速,这个时候人再去踩一下刹车,实际控制权在电脑端,电脑在刹车回收能源,这时人就别出来控制我。只是这时电脑判断有问题了,来不及急刹车。
继续阅读 »
天天上头条,然后评论里第一点赞最多的
独家对话上海维权女车主:请特斯拉到事发路段实地测速
 

e0ZOIQF3lK.png


duhN7PanRb.png

 
这么明显的水军,会不会是友商一起黑呢
毕竟国内的电车厂商背后的财团应该比特斯拉大得多。纯粹猜测。
反正对特斯拉没有好感,这个明显是软件设计的bug。
很早前就有了。 只是一只就没改过来。
刹车时系统回收电力,系统来减速,这个时候人再去踩一下刹车,实际控制权在电脑端,电脑在刹车回收能源,这时人就别出来控制我。只是这时电脑判断有问题了,来不及急刹车。 收起阅读 »

python 破解谷歌人机验证码 运用百度语音识别

谷歌人机交互页面:
https://www.recaptcha.net/recaptcha/api2/demo

ch4vJXhanG4.png

 
如果直接从图片肝,需要收集足够的图片,然后使用yolo或者pytorch进行训练,得到模型后再进行识别。
 
不过这个人机交互验证码有一个语音验证的功能。
 
只要点击一个耳机的图标,然后就变成了语音识别。
播放一段录音,然后输入几个单词,如果单词对了,那么也可以通过。
 

xBi84Ow9N6.png

 
那接下来的问题就简单了,拿到录音->识别录音,转化为文本,然后在输入框输入,就基本大功告成了。
 
英文转文本,网上有不少的AI平台可以白嫖,不过论效果,个人觉得百度的AI效果还不错,起码可以免费调用5W次。
 
完整代码如下:
 
这个是百度识别语音部分:
# -*- coding: utf-8 -*-
# @Time : 2021/4/24 20:50
# @File : baidu_voice_service.py
# @Author : Rocky C@www.30daydo.com

import os
import time

import requests
import sys
import pickle
sys.path.append('..')
from config import API_KEY,SECRET_KEY
from base64 import b64encode
from pathlib import PurePath
import subprocess

BASE = PurePath(__file__).parent

# 需要识别的文件
# 文件格式
# 文件后缀只支持 pcm/wav/amr 格式,极速版额外支持m4a 格式

CUID = '24057753' # 随意
# 采样率
RATE = 16000 # 固定值


ASR_URL = 'http://vop.baidu.com/server_api'

#测试自训练平台需要打开以下信息, 自训练平台模型上线后,您会看见 第二步:“”获取专属模型参数pid:8001,modelid:1234”,按照这个信息获取 dev_pid=8001,lm_id=1234
'''
http://vop.baidu.com/server_api
1537 普通话(纯中文识别) 输入法模型 有标点 支持自定义词库
1737 英语 英语模型 无标点 不支持自定义词库
1637 粤语 粤语模型 有标点 不支持自定义词库
1837 四川话 四川话模型 有标点 不支持自定义词库
1936 普通话远场
'''
DEV_PID = 1737

SCOPE = 'brain_enhanced_asr' # 有此scope表示有asr能力,没有请在网页里开通极速版


class DemoError(Exception):
pass


TOKEN_URL = 'http://openapi.baidu.com/oauth/2.0/token'

def fetch_token():

params = {'grant_type': 'client_credentials',
'client_id': API_KEY,
'client_secret': SECRET_KEY}
r = requests.post(
url=TOKEN_URL,
data=params
)

result = r.json()
if ('access_token' in result.keys() and 'scope' in result.keys()):
if SCOPE and (not SCOPE in result['scope'].split(' ')): # SCOPE = False 忽略检查
raise DemoError('scope is not correct')

return result['access_token']

else:
raise DemoError('MAYBE API_KEY or SECRET_KEY not correct: access_token or scope not found in token response')


""" TOKEN end """

def dump_token(token):
with open(os.path.join(BASE,'token.pkl'),'wb') as fp:
pickle.dump({'token':token},fp)

def load_token(filename):

if not os.path.exists(filename):
token=fetch_token()
dump_token(token)
return token
else:
with open(filename,'rb') as fp:
token = pickle.load(fp)
return token['token']

def recognize_service(token,filename):
FORMAT = filename[-3:]
with open(filename, 'rb') as speech_file:
speech_data = speech_file.read()

length = len(speech_data)
if length == 0:
raise DemoError('file %s length read 0 bytes' % filename)

b64_data = b64encode(speech_data)
params = {'cuid': CUID, 'token': token, 'dev_pid': DEV_PID,'speech':b64_data,'len':length,'format':FORMAT,'rate':RATE,'channel':1}

headers = {
'Content-Type':'application/json',
}
r = requests.post(url=ASR_URL,json=params,headers=headers)
return r.json()

def rate_convertor(filename):
filename = filename.split('.')[0]
CMD=f'ffmpeg.exe -y -i {filename}.mp3 -ac 1 -ar 16000 {filename}.wav'
try:
p=subprocess.Popen(CMD, stdin=subprocess.PIPE)
p.communicate()
time.sleep(1)
except Exception as e:
print(e)
return False,None
else:
return True,f'{filename}.wav'

def clear(file):
try:
os.remove(file)
except Exception as e:
print(e)

def get_voice_text(audio_file):

filename = 'token.pkl'
token = load_token(filename)
convert_status,file = rate_convertor(audio_file)
clear(file)
if not convert_status:
return None

result = recognize_service(token,file)

return result['result'][0]

if __name__ == '__main__':
get_voice_text('1.mp3')



 
然后下面的是获取语音部分,并且点击输入结果。
# -*- coding: utf-8 -*-
# @Time : 2021/4/25 15:16
# @File : download_mp3.py
# @Author : Rocky C@www.30daydo.com



#!/usr/bin/env python3
import os
import subprocess
import time
import re
import requests
import urllib.request
import zipfile
import io
from google.cloud import speech_v1
from random import randint, uniform
from bs4 import BeautifulSoup
from selenium import webdriver
from selenium.common.exceptions import NoSuchElementException
from selenium.webdriver.common.by import By
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait
from google_recaptcha.baidu_voice_service import get_voice_text,clear


class Gcaptcha:

def __init__(self, url):
self.response = None

self.attempts = 0
self.successful = 0
self.failed = 0
self.solved = 0

self.mp3 = 'audio.mp3'
# self.wav='audio.wav'

# Set Chrome to run in headless mode and mute the audio
opts = webdriver.ChromeOptions()
# opts.headless = True
opts.add_argument("--mute-audio")
# opts.add_argument("--headless",)


CHROME_PATH = r'C:\git\EZProject\bin\chromedriver.exe'
self.driver = webdriver.Chrome(executable_path=CHROME_PATH,options=opts)
self.driver.maximize_window()
self.driver.get(url)
self.__bypass_webdriver_check()

# Initialize gcaptcha solver
self.__initialize()

while True:
# Download MP3 file
mp3_file = self.__download_mp3()

# Transcribe MP3 file
result = get_voice_text(self.mp3)

# audio_transcription = transcribe(mp3_file)
# self.transcription.attempts += 1

# If the MP3 file is properly transcribed
if result is not None:
# self.transcription.successful += 1

# Verify transcription
verify = self.__submit_transcription(result)

# Transcription successful with confidence >60%
if verify:
gcaptcha_response = self.__get_response()
self.response = gcaptcha_response
# self.recaptcha.solved += 1

# Delete MP3 file

self.driver.close()
self.driver.quit()
break
# Multiple correct solutions required. Solving again.
else:
self.solved += 1
clear(self.mp3)

# If the MP3 file could not be transcribed
else:
self.failed += 1
clear(self.mp3)

# Click on the "Get a new challenge" button to use a new MP3 file
self.__refresh_mp3()
# time.sleep(uniform(2, 4))



def __initialize(self):
# Access initial gcaptcha iframe
self.driver.switch_to.frame(self.driver.find_element(By.CSS_SELECTOR, 'iframe[name^=a]'))
self.__bypass_webdriver_check()

# Click the gcaptcha checkbox
checkbox = self.driver.find_element(By.CSS_SELECTOR, '#recaptcha-anchor')
self.__mouse_click(checkbox)

# Go back to original content to access second gcaptcha iframe
self.driver.switch_to.default_content()

# Wait roughly 3 seconds for second gcaptcha iframe to load
time.sleep(uniform(2.5, 3))

# Find second gcaptcha iframe
gcaptcha = WebDriverWait(self.driver, 10).until(
EC.presence_of_element_located((By.CSS_SELECTOR, 'iframe[name^=c]'))
)

# Access second gcaptcha iframe
self.driver.switch_to.frame(gcaptcha)
self.__bypass_webdriver_check()

# Click the audio button
audio_button = WebDriverWait(self.driver, 10).until(
EC.presence_of_element_located((By.CSS_SELECTOR, '.rc-button-audio'))
)
self.__mouse_click(audio_button)
time.sleep(0.5)

def __mouse_click(self, element):
cursor = ActionChains(self.driver)
cursor.move_to_element(element)
cursor.pause(uniform(0.3, 0.5))
cursor.click()
cursor.perform()

def __bypass_webdriver_check(self):
self.driver.execute_script(
'const newProto = navigator.__proto__; delete newProto.webdriver; navigator.__proto__ = newProto;')

def __download_mp3(self):
self.driver.switch_to.default_content()
self.driver.switch_to.frame(self.driver.find_element(By.CSS_SELECTOR, 'iframe[name^=c]'))
self.__bypass_webdriver_check()

# Check if the Google servers are blocking us
if len(self.driver.find_elements(By.CSS_SELECTOR, '.rc-doscaptcha-body-text')) == 0:
audio_file = WebDriverWait(self.driver, 10).until(
EC.presence_of_element_located((By.CSS_SELECTOR, '.rc-audiochallenge-tdownload-link'))
)

# Click the play button
play_button = WebDriverWait(self.driver, 10).until(
EC.presence_of_element_located((By.CSS_SELECTOR, '.rc-audiochallenge-play-button > button'))
)
self.__mouse_click(play_button)

# Get URL of MP3 file
audio_url = audio_file.get_attribute('href')

# Predefine the MP3 file name

# Download the MP3 file
try:
urllib.request.urlretrieve(audio_url, self.mp3)
except Exception as e:
print(e)
return None
else:
return self.mp3
else:
Error('Too many requests have been sent to Google. You are currently being blocked by their servers.')
exit(-1)

def __refresh_mp3(self):
self.driver.switch_to.default_content()
self.driver.switch_to.frame(self.driver.find_element(By.CSS_SELECTOR, 'iframe[name^=c]'))
self.__bypass_webdriver_check()

# Click on the refresh button to retrieve a new mp3 file
refresh_button = self.driver.find_element(By.CSS_SELECTOR, '#recaptcha-reload-button')
self.__mouse_click(refresh_button)

def __submit_transcription(self, text):
self.driver.switch_to.default_content()
self.driver.switch_to.frame(self.driver.find_element(By.CSS_SELECTOR, 'iframe[name^=c]'))
self.__bypass_webdriver_check()

# Input field for response
input_field = self.driver.find_element(By.CSS_SELECTOR, '#audio-response')

# Instantly type the full text without delays because Google isn't checking delays between keystrokes
input_field.send_keys(text)

# Click "Verify" button
verify_button = self.driver.find_element(By.CSS_SELECTOR, '#recaptcha-verify-button')
self.__mouse_click(verify_button)

# Wait roughly 3 seconds for verification to complete
time.sleep(uniform(2, 3))

self.driver.switch_to.default_content()
self.driver.switch_to.frame(self.driver.find_element(By.CSS_SELECTOR, 'iframe[name^=a]'))
self.__bypass_webdriver_check()

# Check to see if verified by recaptcha
try:
self.driver.find_element(By.CSS_SELECTOR, '.recaptcha-checkbox-checked')
except NoSuchElementException:
return False
else:
return True

def __get_response(self):
# Switch back to main parent window and get gcaptcha response
self.driver.switch_to.default_content()
response = self.driver.find_element(By.CSS_SELECTOR, '#g-recaptcha-response').get_attribute('value')
return response


class Error(Exception):
def __init__(self, message):
get_files = os.listdir()
match_regex = re.compile(r'^audio\d+.mp3|chromedriver_\w+\d+.zip$')
filtered_files = [f for f in get_files if match_regex.match(f)]

for file in filtered_files:
clear(file)

raise Exception(f'ERROR: {message}')


if __name__=='__main__':
gcaptcha = Gcaptcha('https://www.google.com/recaptcha/api2/demo')
代码里需要你申请一个百度AI的key以便生成token。
最终试了,效果还是达到98%的准确率。
继续阅读 »
谷歌人机交互页面:
https://www.recaptcha.net/recaptcha/api2/demo

ch4vJXhanG4.png

 
如果直接从图片肝,需要收集足够的图片,然后使用yolo或者pytorch进行训练,得到模型后再进行识别。
 
不过这个人机交互验证码有一个语音验证的功能。
 
只要点击一个耳机的图标,然后就变成了语音识别。
播放一段录音,然后输入几个单词,如果单词对了,那么也可以通过。
 

xBi84Ow9N6.png

 
那接下来的问题就简单了,拿到录音->识别录音,转化为文本,然后在输入框输入,就基本大功告成了。
 
英文转文本,网上有不少的AI平台可以白嫖,不过论效果,个人觉得百度的AI效果还不错,起码可以免费调用5W次。
 
完整代码如下:
 
这个是百度识别语音部分:
# -*- coding: utf-8 -*-
# @Time : 2021/4/24 20:50
# @File : baidu_voice_service.py
# @Author : Rocky C@www.30daydo.com

import os
import time

import requests
import sys
import pickle
sys.path.append('..')
from config import API_KEY,SECRET_KEY
from base64 import b64encode
from pathlib import PurePath
import subprocess

BASE = PurePath(__file__).parent

# 需要识别的文件
# 文件格式
# 文件后缀只支持 pcm/wav/amr 格式,极速版额外支持m4a 格式

CUID = '24057753' # 随意
# 采样率
RATE = 16000 # 固定值


ASR_URL = 'http://vop.baidu.com/server_api'

#测试自训练平台需要打开以下信息, 自训练平台模型上线后,您会看见 第二步:“”获取专属模型参数pid:8001,modelid:1234”,按照这个信息获取 dev_pid=8001,lm_id=1234
'''
http://vop.baidu.com/server_api
1537 普通话(纯中文识别) 输入法模型 有标点 支持自定义词库
1737 英语 英语模型 无标点 不支持自定义词库
1637 粤语 粤语模型 有标点 不支持自定义词库
1837 四川话 四川话模型 有标点 不支持自定义词库
1936 普通话远场
'''
DEV_PID = 1737

SCOPE = 'brain_enhanced_asr' # 有此scope表示有asr能力,没有请在网页里开通极速版


class DemoError(Exception):
pass


TOKEN_URL = 'http://openapi.baidu.com/oauth/2.0/token'

def fetch_token():

params = {'grant_type': 'client_credentials',
'client_id': API_KEY,
'client_secret': SECRET_KEY}
r = requests.post(
url=TOKEN_URL,
data=params
)

result = r.json()
if ('access_token' in result.keys() and 'scope' in result.keys()):
if SCOPE and (not SCOPE in result['scope'].split(' ')): # SCOPE = False 忽略检查
raise DemoError('scope is not correct')

return result['access_token']

else:
raise DemoError('MAYBE API_KEY or SECRET_KEY not correct: access_token or scope not found in token response')


""" TOKEN end """

def dump_token(token):
with open(os.path.join(BASE,'token.pkl'),'wb') as fp:
pickle.dump({'token':token},fp)

def load_token(filename):

if not os.path.exists(filename):
token=fetch_token()
dump_token(token)
return token
else:
with open(filename,'rb') as fp:
token = pickle.load(fp)
return token['token']

def recognize_service(token,filename):
FORMAT = filename[-3:]
with open(filename, 'rb') as speech_file:
speech_data = speech_file.read()

length = len(speech_data)
if length == 0:
raise DemoError('file %s length read 0 bytes' % filename)

b64_data = b64encode(speech_data)
params = {'cuid': CUID, 'token': token, 'dev_pid': DEV_PID,'speech':b64_data,'len':length,'format':FORMAT,'rate':RATE,'channel':1}

headers = {
'Content-Type':'application/json',
}
r = requests.post(url=ASR_URL,json=params,headers=headers)
return r.json()

def rate_convertor(filename):
filename = filename.split('.')[0]
CMD=f'ffmpeg.exe -y -i {filename}.mp3 -ac 1 -ar 16000 {filename}.wav'
try:
p=subprocess.Popen(CMD, stdin=subprocess.PIPE)
p.communicate()
time.sleep(1)
except Exception as e:
print(e)
return False,None
else:
return True,f'{filename}.wav'

def clear(file):
try:
os.remove(file)
except Exception as e:
print(e)

def get_voice_text(audio_file):

filename = 'token.pkl'
token = load_token(filename)
convert_status,file = rate_convertor(audio_file)
clear(file)
if not convert_status:
return None

result = recognize_service(token,file)

return result['result'][0]

if __name__ == '__main__':
get_voice_text('1.mp3')



 
然后下面的是获取语音部分,并且点击输入结果。
# -*- coding: utf-8 -*-
# @Time : 2021/4/25 15:16
# @File : download_mp3.py
# @Author : Rocky C@www.30daydo.com



#!/usr/bin/env python3
import os
import subprocess
import time
import re
import requests
import urllib.request
import zipfile
import io
from google.cloud import speech_v1
from random import randint, uniform
from bs4 import BeautifulSoup
from selenium import webdriver
from selenium.common.exceptions import NoSuchElementException
from selenium.webdriver.common.by import By
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait
from google_recaptcha.baidu_voice_service import get_voice_text,clear


class Gcaptcha:

def __init__(self, url):
self.response = None

self.attempts = 0
self.successful = 0
self.failed = 0
self.solved = 0

self.mp3 = 'audio.mp3'
# self.wav='audio.wav'

# Set Chrome to run in headless mode and mute the audio
opts = webdriver.ChromeOptions()
# opts.headless = True
opts.add_argument("--mute-audio")
# opts.add_argument("--headless",)


CHROME_PATH = r'C:\git\EZProject\bin\chromedriver.exe'
self.driver = webdriver.Chrome(executable_path=CHROME_PATH,options=opts)
self.driver.maximize_window()
self.driver.get(url)
self.__bypass_webdriver_check()

# Initialize gcaptcha solver
self.__initialize()

while True:
# Download MP3 file
mp3_file = self.__download_mp3()

# Transcribe MP3 file
result = get_voice_text(self.mp3)

# audio_transcription = transcribe(mp3_file)
# self.transcription.attempts += 1

# If the MP3 file is properly transcribed
if result is not None:
# self.transcription.successful += 1

# Verify transcription
verify = self.__submit_transcription(result)

# Transcription successful with confidence >60%
if verify:
gcaptcha_response = self.__get_response()
self.response = gcaptcha_response
# self.recaptcha.solved += 1

# Delete MP3 file

self.driver.close()
self.driver.quit()
break
# Multiple correct solutions required. Solving again.
else:
self.solved += 1
clear(self.mp3)

# If the MP3 file could not be transcribed
else:
self.failed += 1
clear(self.mp3)

# Click on the "Get a new challenge" button to use a new MP3 file
self.__refresh_mp3()
# time.sleep(uniform(2, 4))



def __initialize(self):
# Access initial gcaptcha iframe
self.driver.switch_to.frame(self.driver.find_element(By.CSS_SELECTOR, 'iframe[name^=a]'))
self.__bypass_webdriver_check()

# Click the gcaptcha checkbox
checkbox = self.driver.find_element(By.CSS_SELECTOR, '#recaptcha-anchor')
self.__mouse_click(checkbox)

# Go back to original content to access second gcaptcha iframe
self.driver.switch_to.default_content()

# Wait roughly 3 seconds for second gcaptcha iframe to load
time.sleep(uniform(2.5, 3))

# Find second gcaptcha iframe
gcaptcha = WebDriverWait(self.driver, 10).until(
EC.presence_of_element_located((By.CSS_SELECTOR, 'iframe[name^=c]'))
)

# Access second gcaptcha iframe
self.driver.switch_to.frame(gcaptcha)
self.__bypass_webdriver_check()

# Click the audio button
audio_button = WebDriverWait(self.driver, 10).until(
EC.presence_of_element_located((By.CSS_SELECTOR, '.rc-button-audio'))
)
self.__mouse_click(audio_button)
time.sleep(0.5)

def __mouse_click(self, element):
cursor = ActionChains(self.driver)
cursor.move_to_element(element)
cursor.pause(uniform(0.3, 0.5))
cursor.click()
cursor.perform()

def __bypass_webdriver_check(self):
self.driver.execute_script(
'const newProto = navigator.__proto__; delete newProto.webdriver; navigator.__proto__ = newProto;')

def __download_mp3(self):
self.driver.switch_to.default_content()
self.driver.switch_to.frame(self.driver.find_element(By.CSS_SELECTOR, 'iframe[name^=c]'))
self.__bypass_webdriver_check()

# Check if the Google servers are blocking us
if len(self.driver.find_elements(By.CSS_SELECTOR, '.rc-doscaptcha-body-text')) == 0:
audio_file = WebDriverWait(self.driver, 10).until(
EC.presence_of_element_located((By.CSS_SELECTOR, '.rc-audiochallenge-tdownload-link'))
)

# Click the play button
play_button = WebDriverWait(self.driver, 10).until(
EC.presence_of_element_located((By.CSS_SELECTOR, '.rc-audiochallenge-play-button > button'))
)
self.__mouse_click(play_button)

# Get URL of MP3 file
audio_url = audio_file.get_attribute('href')

# Predefine the MP3 file name

# Download the MP3 file
try:
urllib.request.urlretrieve(audio_url, self.mp3)
except Exception as e:
print(e)
return None
else:
return self.mp3
else:
Error('Too many requests have been sent to Google. You are currently being blocked by their servers.')
exit(-1)

def __refresh_mp3(self):
self.driver.switch_to.default_content()
self.driver.switch_to.frame(self.driver.find_element(By.CSS_SELECTOR, 'iframe[name^=c]'))
self.__bypass_webdriver_check()

# Click on the refresh button to retrieve a new mp3 file
refresh_button = self.driver.find_element(By.CSS_SELECTOR, '#recaptcha-reload-button')
self.__mouse_click(refresh_button)

def __submit_transcription(self, text):
self.driver.switch_to.default_content()
self.driver.switch_to.frame(self.driver.find_element(By.CSS_SELECTOR, 'iframe[name^=c]'))
self.__bypass_webdriver_check()

# Input field for response
input_field = self.driver.find_element(By.CSS_SELECTOR, '#audio-response')

# Instantly type the full text without delays because Google isn't checking delays between keystrokes
input_field.send_keys(text)

# Click "Verify" button
verify_button = self.driver.find_element(By.CSS_SELECTOR, '#recaptcha-verify-button')
self.__mouse_click(verify_button)

# Wait roughly 3 seconds for verification to complete
time.sleep(uniform(2, 3))

self.driver.switch_to.default_content()
self.driver.switch_to.frame(self.driver.find_element(By.CSS_SELECTOR, 'iframe[name^=a]'))
self.__bypass_webdriver_check()

# Check to see if verified by recaptcha
try:
self.driver.find_element(By.CSS_SELECTOR, '.recaptcha-checkbox-checked')
except NoSuchElementException:
return False
else:
return True

def __get_response(self):
# Switch back to main parent window and get gcaptcha response
self.driver.switch_to.default_content()
response = self.driver.find_element(By.CSS_SELECTOR, '#g-recaptcha-response').get_attribute('value')
return response


class Error(Exception):
def __init__(self, message):
get_files = os.listdir()
match_regex = re.compile(r'^audio\d+.mp3|chromedriver_\w+\d+.zip$')
filtered_files = [f for f in get_files if match_regex.match(f)]

for file in filtered_files:
clear(file)

raise Exception(f'ERROR: {message}')


if __name__=='__main__':
gcaptcha = Gcaptcha('https://www.google.com/recaptcha/api2/demo')
代码里需要你申请一个百度AI的key以便生成token。
最终试了,效果还是达到98%的准确率。 收起阅读 »