华宝油气自动化申购脚本 AutoJS
运行效果图:https://v.qq.com/x/page/u3155gvuxvt.html
因为最近两周的华宝油气都呈现很大的折价,但是限购,所以拖拉机申购非常的麻烦,需要一路点击,非常的耗时间,而且容易出错,容易点重复了,导致另外一个股东号没有申购。
所以自己用appium写了个手机自动化申购的脚本,只是它的部署相当不方便,对于一般小白几乎很难独立实现。在上一篇文章中埋了个伏笔 转债水位在降低 当时还准备基于appium写个教程来着。
最近发现有一个叫auto.js的app,基于JS代码的自动化工具,可以很方便的操控手机,只需要在手机上安装一个app,然后写一段JS脚本,然后运行就可以了,部署简化了不少。
后台回复:autojs 会提供相应的app下载与源码打包。
先看运行效果图:
运行的视频文件下面:
https://v.qq.com/x/page/u3155gvuxvt.html
脚本代码入口函数:
完整代码:
[i]安装使用步骤:
安装autojs app
[/i]
[/*]
[/list]
[/*]
[/list]
[/*]
[/list]
[i]
然后就静静的等待脚本执行完成,你的6个股东号就全部打完啦。如果你有多个证券账户,需要你退出当前的账户,然后登陆下一个账号,然后继续运行这个脚本即可。
后台回复:autojs 就可以获取autojs的app与上面的源码打包。
PS:如果你有有趣的想法要验证或者苦于没有数据无从下手,可以后台留言,一起交流,笔者会尝试帮你们验证分析。
关注公众号:
[/i] 收起阅读 »
因为最近两周的华宝油气都呈现很大的折价,但是限购,所以拖拉机申购非常的麻烦,需要一路点击,非常的耗时间,而且容易出错,容易点重复了,导致另外一个股东号没有申购。
所以自己用appium写了个手机自动化申购的脚本,只是它的部署相当不方便,对于一般小白几乎很难独立实现。在上一篇文章中埋了个伏笔 转债水位在降低 当时还准备基于appium写个教程来着。
最近发现有一个叫auto.js的app,基于JS代码的自动化工具,可以很方便的操控手机,只需要在手机上安装一个app,然后写一段JS脚本,然后运行就可以了,部署简化了不少。
后台回复:autojs 会提供相应的app下载与源码打包。
先看运行效果图:
运行的视频文件下面:
https://v.qq.com/x/page/u3155gvuxvt.html
脚本代码入口函数:
main("162411", "6", "100");其中第二个参数是申购的次数,场内的最多6个股东号,所以设置为6。
完整代码:
//可转债量化分析
function main(code, count, money) {
log(code, count, money);
if (!code) {
toast("请输入基金代码");
return;
}
if (!count) {
toast("股东账户数量");
return;
}
if (!money) {
toast("申购金额");
return;
}
app.launchApp("中国银河证券");
waitForPackage("com.galaxy.stock");
log("成功打开银河证券");
sleep(1000);
// 切换到【交易】tab
const tradeBtn = text("交易")
.findOne()
.parent()
.parent();
log(tradeBtn);
tradeBtn.click();
//点击【场内基金】
sleep(1000);
const internalFund = text("场内基金")
.findOnce()
.parent();
internalFund.click();
//点击【基金申购】
waitForActivity("cn.com.chinastock.trade.activity.LofActivity");
const fundPurchase = text("基金申购")
.findOnce()
.parent();
fundPurchase.click();
// 自动填信息
sleep(1000);
purchaseFund(code, count, money);
}
function purchaseFund(code, count, money) {
for (let i = 0; i < count; i++) {
log(code, count, money);
const codeInput = id("stockCode").findOne();
codeInput.click();
codeInput.setText(code);
sleep(1000);
const accountSelect = id("secuidList").findOne();
accountSelect.click();
sleep(1000);
const options = className("CheckedTextView").find();
click(options[i].bounds().left + 2, options[i].bounds().top + 2);
sleep(300);
const orderAmount = id("orderAmount")
.findOnce()
.children()[0];
log(orderAmount);
orderAmount.setText(money);
sleep(300);
id("order")
.findOnce()
.click();
sleep(6000);
id("acceptedCb")
.findOnce()
.click();
id("okBtn")
.findOnce()
.click();
sleep(6000);
click("本人已认真阅读并理解上述内容");
sleep(200);
click("我接受");
sleep(200);
click("本人已认真阅读并理解上述内容");
sleep(200)
click("我接受");
sleep(7000);
click("本人已认真阅读并理解上述内容");
sleep(200);
click("我接受");
sleep(500);
text('确认申购').findOnce().click();
sleep(1000);
text("确定")
.findOnce()
.click();
sleep(1000);
}
}
main("162411", "6", "100");[/i][/i]
[i]安装使用步骤:
安装autojs app
[/i]
- [i]手机设置无障碍模式,把autojs添加进去,一般按住app的时候会提示引导你这么操作[/i][list][*][i]打开autojs app,把上面的JS代码复制进去[/i][list][*][i]登录你的X河牌拖拉机[/i][list][*][i]在autojs app里面点击执行[/i]
[/*]
[/list]
[/*]
[/list]
[/*]
[/list]
[i]
然后就静静的等待脚本执行完成,你的6个股东号就全部打完啦。如果你有多个证券账户,需要你退出当前的账户,然后登陆下一个账号,然后继续运行这个脚本即可。
后台回复:autojs 就可以获取autojs的app与上面的源码打包。
PS:如果你有有趣的想法要验证或者苦于没有数据无从下手,可以后台留言,一起交流,笔者会尝试帮你们验证分析。
关注公众号:
[/i] 收起阅读 »
python asyncio aiohttp motor异步爬虫例子 定时抓取bilibili首页热度网红
使用的异步库: aiohttp【http异步库】,motor【mongo异步库】
AsyncIOMotorClient(connect_uri)
motor连接带用户名和密码的方法和pymongo一致。
connect_uri = f'mongodb://{user}:{password}@{host}:{port}'
爬取的数据图:
原创文章,转载请注明:http://30daydo.com/article/605
需要源码,可私信。
收起阅读 »
AsyncIOMotorClient(connect_uri)
motor连接带用户名和密码的方法和pymongo一致。
connect_uri = f'mongodb://{user}:{password}@{host}:{port}'
# -*- coding: utf-8 -*-
# website: http://30daydo.com
# @Time : 2020/9/22 10:07
# @File : bilibili_hot_anchor.py
# 异步爬取首页与列表
import asyncio
import datetime
import aiohttp
import re
import time
from motor.motor_asyncio import AsyncIOMotorClient
from parsel import Selector
from settings import _json_data
SLEEP = 60 * 10
INFO = _json_data['mongo']['arm']
host = INFO['host']
port = INFO['port']
user = INFO['user']
password = INFO['password']
connect_uri = f'mongodb://{user}:{password}@{host}:{port}'
client = AsyncIOMotorClient(connect_uri)
db = client['db_parker']
home_url = 'https://www.bilibili.com/ranking'
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:57.0) Gecko/20100101 Firefox/57.0',
'Accept-Language': 'zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2'}
def convertor(number_str):
'''
将小数点的万变为整数
:param number_str:
:return:
'''
number = re.search('(\d+\.+\d+)', number_str)
if number:
number = float(number.group(1))
if re.search('万', number_str):
number = int(number * 10000)
else:
number = 0
return number
async def home_page():
async with aiohttp.ClientSession() as session:
while True:
start = time.time()
async with session.get(url=home_url, headers=headers) as response:
html = await response.text()
resp = Selector(text=html)
items = resp.xpath('//ul[@class="rank-list"]/li')
for item in items:
json_data = {}
number = item.xpath('.//div[@class="num"]/text()').extract_first()
info = item.xpath('.//div[@class="info"][1]')
title = info.xpath('.//a/text()').extract_first()
detail_url = info.xpath('.//a/@href').extract_first()
play_number = info.xpath('.//div[@class="detail"]/span[1]/text()').extract_first()
viewing_number = info.xpath('.//div[@class="detail"]/span[2]/text()').extract_first()
json_data['number'] = int(number)
json_data['title'] = title
json_data['play_number'] = convertor(play_number)
json_data['viewing_number'] = convertor(viewing_number)
json_data['url'] = detail_url
task = asyncio.create_task(detail_list(session, detail_url, json_data))
# await detail_url()
end = time.time()
print(f'time used {end-start}')
await asyncio.sleep(SLEEP) # 暂停10分钟
print(f'sleep for {SLEEP}')
async def detail_list(session, url, json_data):
async with session.get(url, headers=headers) as response:
response = await response.text()
await parse_detail(response, json_data)
async def parse_detail(html, json_data=None):
resp = Selector(text=html)
info = resp.xpath('//div[@id="v_desc"]/div[@class="info open"]/text()').extract_first()
if not info:
info = '这个家伙很懒'
json_data['info'] = info.strip()
current = datetime.datetime.now()
json_data['crawltime'] = current
await db['bilibili'].update_one({'url': json_data['url']}, {'$set': json_data}, True, True)
loop = asyncio.get_event_loop()
loop.run_until_complete(home_page())
爬取的数据图:
原创文章,转载请注明:http://30daydo.com/article/605
需要源码,可私信。
收起阅读 »
Elastic Search报错:Fielddata is disabled on text fields by default
在使用 ElasticSearch 的时候,如果索引中的字段是 text 类型,针对该字段聚合、排序和查询的时候常会出现 Fielddata is disabled on text fields by default. Set fielddata=true 的错误。本文总结这个错误出现的原因,可能的修复方法等。
常见原因
在 ElasticSearch 中,Fielddata 默认在 text 类型的字段时是不启用的。设想,如果默认打开,那么你的数据中,每个字符串大概率不一样的话,那么这个字段需要的集合大小(Cardinality)会非常大。
而这个字段是需要存在内存中的 (heap),因此不可能默认打开。所以如果你从一个 script 来对一个 text 字段进行排序、聚合或者查询的话,就会出现这个错误。Fielddata is disabled on text fields by default. Set `fielddata=true` on [`你的字段名字`] in order to load fielddata in memory by uninverting the inverted index. Note that this can however use significant memory.
Fielddata is disabled on text fields by default 解答方法看这篇:
ES 如何解决 Fielddata is disabled on text fields by default 错误
收起阅读 »
常见原因
在 ElasticSearch 中,Fielddata 默认在 text 类型的字段时是不启用的。设想,如果默认打开,那么你的数据中,每个字符串大概率不一样的话,那么这个字段需要的集合大小(Cardinality)会非常大。
而这个字段是需要存在内存中的 (heap),因此不可能默认打开。所以如果你从一个 script 来对一个 text 字段进行排序、聚合或者查询的话,就会出现这个错误。Fielddata is disabled on text fields by default. Set `fielddata=true` on [`你的字段名字`] in order to load fielddata in memory by uninverting the inverted index. Note that this can however use significant memory.
Fielddata is disabled on text fields by default 解答方法看这篇:
ES 如何解决 Fielddata is disabled on text fields by default 错误
收起阅读 »
开源网盘系统推荐 sharelist
不错的一个网盘系统https://github.com/reruin/sharelist
支持以下功能:
挂载GoogleDrive
挂载OneDrive(含世纪互联)
挂载天翼云盘(支持账号密码挂载)
挂载和彩云
挂载本地文件
挂载GitHub
挂载蓝奏云
挂载h5ai
挂载WebDAV
挂载SFTP
【别问我是怎么知道的】当时在网络上搜刮到一个别人的共享盘,里面居然一堆的QQ密码数据库,网易邮箱密码库,上百G的数据库,哎,网名的隐私在中国互联网连P都不是哈。
收起阅读 »
支持以下功能:
挂载GoogleDrive
挂载OneDrive(含世纪互联)
挂载天翼云盘(支持账号密码挂载)
挂载和彩云
挂载本地文件
挂载GitHub
挂载蓝奏云
挂载h5ai
挂载WebDAV
挂载SFTP
【别问我是怎么知道的】当时在网络上搜刮到一个别人的共享盘,里面居然一堆的QQ密码数据库,网易邮箱密码库,上百G的数据库,哎,网名的隐私在中国互联网连P都不是哈。
收起阅读 »
python3.8海象运算符
海象运算符( := )
这个「:=」横过来看是不是有点像海象的脸?这是一个新的 Python 语法,可以在进行条件判断时直接为变量赋值。
过去我们需要首先对某个变量进行赋值,然后进行条件判断。
而使用海象运算符后,我们可以直接为变量赋值:
PS:
python的版本更新最喜欢搞这一类的小动作,仅仅为了节省那么一两行代码弄得代码无法向下兼容。
收起阅读 »
这个「:=」横过来看是不是有点像海象的脸?这是一个新的 Python 语法,可以在进行条件判断时直接为变量赋值。
过去我们需要首先对某个变量进行赋值,然后进行条件判断。
m = re.match(p1, line)
if m:
return m.group(1)
else:
m = re.match(p2, line)
if m:
return m.group(2)
else:
m = re.match(p3, line)
...
而使用海象运算符后,我们可以直接为变量赋值:
if m := re.match(p1, line):
return m.group(1)
elif m := re.match(p2, line):
return m.group(2)
elif m := re.match(p3, line):
PS:
python的版本更新最喜欢搞这一类的小动作,仅仅为了节省那么一两行代码弄得代码无法向下兼容。
收起阅读 »
港股打新的基础知识
……港股打新的基础知识……
其实我们不提倡长期炒港股,我们打新即可。今天就介绍些港股打新的基础知识给大家参考。
1、招股书:这个和我们大A是一样的,上市公司发行股票前要发布招股说明书,把公司的基本情况、近三年业绩情况、财务指标数据、行业前景等等都写在这里,基本上得有三四百页。
2、招股价:通常港股上市前会让公众认购的股价,会给一个范围,比如招股价1-3港元,那么地区定价就在1港元,中位数2港元,高区定价就是3港元,公司会结合公众认购的情况定价。
3、超额认购倍数:认购金额/募资额的倍数。通常公开发售超够倍数动态监测才有,具体数据只能在中签公开日才能知道。倍数越高,说明这个股票受到市场追捧,大家都希望认购,后期股票上市时上涨、大涨的概率就越高。
4、回拨机制:港股发行股票是有回拨机制的,比如公开发售占总募资股份的10%,国际配售占90%,如果认购太火爆,上市公司和承销商就可以根据认购倍数来进行调整,这个调整就叫回拨机制。超额认购倍数如果在15>50>100倍,则对应回拨比例30%、40%、50%最常见。回拨越多,说明市场需求越强,上涨概率越大。
5、绿鞋机制:港股中比较常见,因为港股打新并非必赚钱,新港股有一半上市就破发。绿鞋机制其实就是护盘机制,承销商就有维护上市股价稳定的责任,防止大起大落。
6、保荐人:保荐人一般是证券公司,就是辅导上市公司上市和信息披露的券商,并且承担担保责任。如果保荐人是国际知名企业,并且有很多辅导上市公司的案例,形成了自身的品牌,那么新股上市上涨的概率较大。
7、基石投资者:港股是有基石投资者的,主要是看好上市公司的机构、企业集团或上市公司的亲朋好友提前持有一些原始股,表示对上市公司未来前景的肯定,能给市场增强信心,因为基石投资者持有的股票需要锁定半年才能抛售。
8、新股认购:港股认购新股不需要市值,可用现金认购,也可融资认购。现金认购就是你账户有多少钱就认购多少,大部分券商现金认购免费。融资认购就是上杠杆,大部分券商支持10-20倍融资认购,少部分支持50倍认购,大部分券商融资认购既收手续费,又收融资利息。
9、甲组和乙组:港股打新根据申购金额不同分组,500万以下为甲组(小散户),500万以上为乙组(大户),公开发售甲乙组各50%,通常乙组人少,所以中签数量会多,收益与亏损都将同步放大。有时候融资多了就会冲到乙组。
10、孖展:其实是英文Margin,即保证金,可以认为是融资认购打新加杠杆。孖展越多超够倍数就越多,孖展倍数越高说明大家愿意上杠杆参与,新股上涨的概率就越大。
11、入门资金:港股的1手每个股票都不同,有些1手是100股,有些是1000股,甚至有些是2000股,每个股票都不一样,在招股说明书中一定要看好。同时这也决定了打1手需要的最低金额,即入门资金。比如招股价范围是1-3港元,1手是2000股,那么最低申购1手冻结的资金范围就是2000港元-6000港元之间。
12、一手中签率:港股打新就这点好,为了保证大家参与都有钱挣,港交所规定每个账户认购1手新股的中签率必须是最高的。比如你1个账户认购了1手新股,中1签的概率可能为80%;但如果你1个账户认购10手新股,你中1签的概率可能是10%。具体怎么操作的我也还不清楚,只知道这就是港股的规则。
正是一手中签率最高的原则,决定了港股打新的玩法:同一身份证开多账户,每账户配置1-2万港元,一手申购,提高中签率!
收起阅读 »
其实我们不提倡长期炒港股,我们打新即可。今天就介绍些港股打新的基础知识给大家参考。
1、招股书:这个和我们大A是一样的,上市公司发行股票前要发布招股说明书,把公司的基本情况、近三年业绩情况、财务指标数据、行业前景等等都写在这里,基本上得有三四百页。
2、招股价:通常港股上市前会让公众认购的股价,会给一个范围,比如招股价1-3港元,那么地区定价就在1港元,中位数2港元,高区定价就是3港元,公司会结合公众认购的情况定价。
3、超额认购倍数:认购金额/募资额的倍数。通常公开发售超够倍数动态监测才有,具体数据只能在中签公开日才能知道。倍数越高,说明这个股票受到市场追捧,大家都希望认购,后期股票上市时上涨、大涨的概率就越高。
4、回拨机制:港股发行股票是有回拨机制的,比如公开发售占总募资股份的10%,国际配售占90%,如果认购太火爆,上市公司和承销商就可以根据认购倍数来进行调整,这个调整就叫回拨机制。超额认购倍数如果在15>50>100倍,则对应回拨比例30%、40%、50%最常见。回拨越多,说明市场需求越强,上涨概率越大。
5、绿鞋机制:港股中比较常见,因为港股打新并非必赚钱,新港股有一半上市就破发。绿鞋机制其实就是护盘机制,承销商就有维护上市股价稳定的责任,防止大起大落。
6、保荐人:保荐人一般是证券公司,就是辅导上市公司上市和信息披露的券商,并且承担担保责任。如果保荐人是国际知名企业,并且有很多辅导上市公司的案例,形成了自身的品牌,那么新股上市上涨的概率较大。
7、基石投资者:港股是有基石投资者的,主要是看好上市公司的机构、企业集团或上市公司的亲朋好友提前持有一些原始股,表示对上市公司未来前景的肯定,能给市场增强信心,因为基石投资者持有的股票需要锁定半年才能抛售。
8、新股认购:港股认购新股不需要市值,可用现金认购,也可融资认购。现金认购就是你账户有多少钱就认购多少,大部分券商现金认购免费。融资认购就是上杠杆,大部分券商支持10-20倍融资认购,少部分支持50倍认购,大部分券商融资认购既收手续费,又收融资利息。
9、甲组和乙组:港股打新根据申购金额不同分组,500万以下为甲组(小散户),500万以上为乙组(大户),公开发售甲乙组各50%,通常乙组人少,所以中签数量会多,收益与亏损都将同步放大。有时候融资多了就会冲到乙组。
10、孖展:其实是英文Margin,即保证金,可以认为是融资认购打新加杠杆。孖展越多超够倍数就越多,孖展倍数越高说明大家愿意上杠杆参与,新股上涨的概率就越大。
11、入门资金:港股的1手每个股票都不同,有些1手是100股,有些是1000股,甚至有些是2000股,每个股票都不一样,在招股说明书中一定要看好。同时这也决定了打1手需要的最低金额,即入门资金。比如招股价范围是1-3港元,1手是2000股,那么最低申购1手冻结的资金范围就是2000港元-6000港元之间。
12、一手中签率:港股打新就这点好,为了保证大家参与都有钱挣,港交所规定每个账户认购1手新股的中签率必须是最高的。比如你1个账户认购了1手新股,中1签的概率可能为80%;但如果你1个账户认购10手新股,你中1签的概率可能是10%。具体怎么操作的我也还不清楚,只知道这就是港股的规则。
正是一手中签率最高的原则,决定了港股打新的玩法:同一身份证开多账户,每账户配置1-2万港元,一手申购,提高中签率!
收起阅读 »
python pyexecjs执行含有中文字符的js脚本报错
报错信息如下:
使用nodejs直接执行js是没有问题,同样代码在linux上执行也没有问题。
原因是windows的默认编码为cp396,修改subprocess.py文件的默认编码就可以解决。
把上面的encoding=None改为 encoding="utf-8",就可以了。 收起阅读 »
File "C:\ProgramData\Anaconda3\lib\threading.py", line 926, in _bootstrap_inner
self.run()
File "C:\ProgramData\Anaconda3\lib\threading.py", line 870, in run
self._target(*self._args, **self._kwargs)
File "C:\ProgramData\Anaconda3\lib\subprocess.py", line 1238, in _readerthread
buffer.append(fh.read())
UnicodeDecodeError: 'gbk' codec can't decode byte 0xbd in position 52: illegal multibyte sequence
File "C:\ProgramData\Anaconda3\lib\site-packages\execjs\_external_runtime.py", line 103, in _exec_with_pipe
stdoutdata, stderrdata = p.communicate(input=input)
File "C:\ProgramData\Anaconda3\lib\subprocess.py", line 939, in communicate
stdout, stderr = self._communicate(input, endtime, timeout)
File "C:\ProgramData\Anaconda3\lib\subprocess.py", line 1288, in _communicate
stdout = stdout[0]
IndexError: list index out of range
使用nodejs直接执行js是没有问题,同样代码在linux上执行也没有问题。
原因是windows的默认编码为cp396,修改subprocess.py文件的默认编码就可以解决。
def __init__(self, args, bufsize=-1, executable=None,
stdin=None, stdout=None, stderr=None,
preexec_fn=None, close_fds=True,
shell=False, cwd=None, env=None, universal_newlines=None,
startupinfo=None, creationflags=0,
restore_signals=True, start_new_session=False,
pass_fds=(), *, encoding="None", errors=None, text=None):
把上面的encoding=None改为 encoding="utf-8",就可以了。 收起阅读 »
2020-08-19招商证券app和电脑客户端都无法登录 一整天无法登录
不知道是咋回事。 IP地址被封了?
一整天无法登录,这个故障也太大了吧。
一整天无法登录,这个故障也太大了吧。
爬虫nike登录流程抓包分析
<占坑> 敬请期待。
在Docker中配置Kibana连接ElasticSearch的一些小坑
之前编译部署的时候只需要在config/kibana.yaml 中修改host ,把默认的 http://elasticsearch:9200 改为 http://127.0.0.1:9200 , 如果你的ElasticSearch带密码访问,只需在下面加多2行
elasticseacrh.user='elastic'
elasticsearch.password='xxxxxx' # 你之前配置ES时设置的密码
BUT, 上面的配置在docker环境下无法正常启动使用kibana, 通过docker logs 容器ID, 查看的日志信息:
elasticseacrh.user='elastic'
elasticsearch.password='xxxxxx' # 你之前配置ES时设置的密码
BUT, 上面的配置在docker环境下无法正常启动使用kibana, 通过docker logs 容器ID, 查看的日志信息:
log [17:39:09.057] [warning][data][elasticsearch] No living connections使用curl访问127.0.0.1:920也是正常的,后来想到docker貌似没有配置桥接网络,两个docker可能无法互通,故把kibana.yaml里面的host改为主机的真实IP(内网172网段ip),然后问题就得到解决了。 收起阅读 »
log [17:39:09.058] [warning][licensing][plugins] License information could not be obtained from Elasticsearch due to Error: No Living connections error
log [17:39:09.635] [warning][admin][elasticsearch] Unable to revive connection: http://127.0.0.1:9200/
log [17:39:09.636] [warning][admin][elasticsearch] No living connections
log [17:39:12.137] [warning][admin][elasticsearch] Unable to revive connection: http://127.0.0.1:9200/
log [17:39:12.138] [warning][admin][elasticsearch] No living connections
log [17:39:14.640] [warning][admin][elasticsearch] Unable to revive connection: http://127.0.0.1:9200/
log [17:39:14.640] [warning][admin][elasticsearch] No living connections
log [17:39:17.143] [warning][admin][elasticsearch] Unable to revive connection: http://127.0.0.1:9200/
log [17:39:17.143] [warning][admin][elasticsearch] No living connections
log [17:39:19.645] [warning][admin][elasticsearch] Unable to revive connection: http://127.0.0.1:9200/
一条命令要python统一江湖
$alias python4=gcc python5=rustc python6=javac python7=node那好不送哈哈。
Have a reset then enjoy the next
Hopefully ~~
2020-06-29
2020-06-29
深圳住房公积金验证码 识别破解
http://gjj.sz.gov.cn/fzgn/zfcq/index.html
比较常规的验证码,使用keras全连接层,cv切割后每个字符只需要20个样本就达到准确率99%。
需要模型或者代码的私聊。 收起阅读 »
PyQt5自定义控件
PyQt5包含种类丰富的控件。但能满足所有需求的控件库是不存在的。通常控件库只提供了像按钮、文本控件、滑块等最常用的控件。但如果需要某种特殊的控件,我们只能自己动手来实现。 自定义控件需要使用工具库提供的绘图工具,可能有两种方式:在已有的控件上进行拓展或从头开始创建自定义控件。
Burning widget(烧录控件)
这个控件可能会在Nero,K3B或其他CD/DVD烧录软件中见到。
在示例中我们使用了滑块与一个自定义控件。自定义控件受滑块控制。控件显示了媒体介质的容量和剩余空间。该控件的最小值为1,最大值为750。在值超过700时颜色变为红色。这通常意味着超刻(即实际写入光盘的容量超过刻录盘片官方标称容量的一种操作)。
BurningWidget控件通过QHBoxLayout与QVBoxLayout置于窗体的底部。
烧录的控件,它基于QWidget
控件采用了动态绘制技术。窗体越大,控件也随之变大;反之亦然。这也是我们需要计算自定义控件的载体控件(即窗体)尺寸的原因。till参数定义了需要绘制的总尺寸,它根据slider控件计算得出,是整体区域的比例值。full参数定义了红色区域的绘制起点。注意在绘制时为取得较大精度而使用的浮点数运算。
实际的绘制分三个步骤。黄色或红黄矩形的绘制,然后是刻度线的绘制,最后是刻度值的绘制。
收起阅读 »
Burning widget(烧录控件)
这个控件可能会在Nero,K3B或其他CD/DVD烧录软件中见到。
# -*- coding: utf-8 -*-
"""
PyQt5 tutorial
In this example, we create a custom widget.
"""
import sys
from PyQt5.QtWidgets import (QWidget, QSlider, QApplication,
QHBoxLayout, QVBoxLayout)
from PyQt5.QtCore import QObject, Qt, pyqtSignal
from PyQt5.QtGui import QPainter, QFont, QColor, QPen
class Communicate(QObject):
updateBW = pyqtSignal(int)
class BurningWidget(QWidget):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
self.setMinimumSize(1, 30)
self.value = 75
self.num = [75, 150, 225, 300, 375, 450, 525, 600, 675]
def setValue(self, value):
self.value = value
def paintEvent(self, e):
qp = QPainter()
qp.begin(self)
self.drawWidget(qp)
qp.end()
def drawWidget(self, qp):
font = QFont('Serif', 7, QFont.Light)
qp.setFont(font)
size = self.size()
w = size.width()
h = size.height()
step = int(round(w / 10.0))
till = int(((w / 750.0) * self.value))
full = int(((w / 750.0) * 700))
if self.value >= 700:
qp.setPen(QColor(255, 255, 255))
qp.setBrush(QColor(255, 255, 184))
qp.drawRect(0, 0, full, h)
qp.setPen(QColor(255, 175, 175))
qp.setBrush(QColor(255, 175, 175))
qp.drawRect(full, 0, till - full, h)
else:
qp.setPen(QColor(255, 255, 255))
qp.setBrush(QColor(255, 255, 184))
qp.drawRect(0, 0, till, h)
pen = QPen(QColor(20, 20, 20), 1,
Qt.SolidLine)
qp.setPen(pen)
qp.setBrush(Qt.NoBrush)
qp.drawRect(0, 0, w - 1, h - 1)
j = 0
for i in range(step, 10 * step, step):
qp.drawLine(i, 0, i, 5)
metrics = qp.fontMetrics()
fw = metrics.width(str(self.num[j]))
qp.drawText(i - fw / 2, h / 2, str(self.num[j]))
j = j + 1
class Example(QWidget):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
sld = QSlider(Qt.Horizontal, self)
sld.setFocusPolicy(Qt.NoFocus)
sld.setRange(1, 750)
sld.setValue(75)
sld.setGeometry(30, 40, 150, 30)
self.c = Communicate()
self.wid = BurningWidget()
self.c.updateBW[int].connect(self.wid.setValue)
sld.valueChanged[int].connect(self.changeValue)
hbox = QHBoxLayout()
hbox.addWidget(self.wid)
vbox = QVBoxLayout()
vbox.addStretch(1)
vbox.addLayout(hbox)
self.setLayout(vbox)
self.setGeometry(300, 300, 390, 210)
self.setWindowTitle('Burning widget')
self.show()
def changeValue(self, value):
self.c.updateBW.emit(value)
self.wid.repaint()
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = Example()
sys.exit(app.exec_())
在示例中我们使用了滑块与一个自定义控件。自定义控件受滑块控制。控件显示了媒体介质的容量和剩余空间。该控件的最小值为1,最大值为750。在值超过700时颜色变为红色。这通常意味着超刻(即实际写入光盘的容量超过刻录盘片官方标称容量的一种操作)。
BurningWidget控件通过QHBoxLayout与QVBoxLayout置于窗体的底部。
class BurningWidget(QWidget):
def __init__(self):
super().__init__()
烧录的控件,它基于QWidget
self.setMinimumSize(1, 30)我们改变了控件的最小大小(高度),默认值为有点小。
font = QFont('Serif', 7, QFont.Light)我们使用一个比默认要小的字体。
qp.setFont(font)
size = self.size()
w = size.width()
h = size.height()
step = int(round(w / 10.0))
till = int(((w / 750.0) * self.value))
full = int(((w / 750.0) * 700))
控件采用了动态绘制技术。窗体越大,控件也随之变大;反之亦然。这也是我们需要计算自定义控件的载体控件(即窗体)尺寸的原因。till参数定义了需要绘制的总尺寸,它根据slider控件计算得出,是整体区域的比例值。full参数定义了红色区域的绘制起点。注意在绘制时为取得较大精度而使用的浮点数运算。
实际的绘制分三个步骤。黄色或红黄矩形的绘制,然后是刻度线的绘制,最后是刻度值的绘制。
metrics = qp.fontMetrics()我们使用字体度量来绘制文本。我们必须知道文本的宽度,以中心垂直线。
fw = metrics.width(str(self.num[j]))
qp.drawText(i-fw/2, h/2, str(self.num[j]))
def changeValue(self, value):当滑块发生移动时,changeValue()方法会被调用。在方法内我们触发了一个自定义的updateBW信号,其参数是当前滚动条的值。该值被用于计算Burning widget的容量值。然后对控件进行重绘。
self.c.updateBW.emit(value)
self.wid.repaint()
收起阅读 »
Windows安装pyminizip
python3直接安装会报错:
pip install pyminizip
电脑需要安装vc的编译库,或者在其他机子上把pyd文件拷贝到程序的当前目录。
pip install pyminizip
电脑需要安装vc的编译库,或者在其他机子上把pyd文件拷贝到程序的当前目录。
996走起
最近996真起劲
redis desktop manager windows客户端
原来用的QT写的。
怪不得这么垃圾。。。。。
怪不得这么垃圾。。。。。
pyqt5 QRect在哪个类
最新的版本是在 QtCore里面的
from PyQt5.QtCore import Qt,QRect
2020-03-27 新事情坚持
持续一周的出差,学到的一些东西。
接下来的30天,要养成的习惯:
1. 早睡早起
2. 持续比例的输出。(有输入就要有输出)
3. 锻炼身体
4. 先专注一件事情,让他变为习惯后再攻克另外一件事情。
接下来的30天,要养成的习惯:
1. 早睡早起
2. 持续比例的输出。(有输入就要有输出)
3. 锻炼身体
4. 先专注一件事情,让他变为习惯后再攻克另外一件事情。