开发

pip离线打包与安装python库

1、从本机导出第三方库列表 pip freeze > requirements.txt 2、根据列表从网络下载第三方库安装包 pip download -d packages -r requirements.txt 理论上pip download命令可以通过–no-index –find-links参数指定从离线环境下载安装包,但是我估计所谓的离线安装包并不等同于\Python36\Lib\site-packages这个目录,毕竟这个目录是安装完后的包目录。如果让–find-links指向这个目录的话,有可能成功也有可能失败,失败了pip也不给详细的错误输出。 所以不管怎么说,还是乖乖的从网上的pip仓库下载安装包吧。 3、将packages文件夹与requirements.txt文件拷贝到目标机器后,在目标机安装第三方库 pip install –no-index […]

pyinstaller打包py程序

1. 基本语法 pyinstaller命令行的语法是: pyinstaller [options] script [script …] | specfile 通常情况只需要将命令行移动到需要打包的脚本根目录下,然后运行: # 打包myscript.py脚本,生成一个包含可执行文件的目录 pyinstaller myscript.py # 打包myscript.py脚本,生成单个可执行文件,并且关闭终端输出 pyinstaller –onefile –windowed

pyqt5

这两个礼拜做一个报文发送的后台守护程序,用到了pyqt5做用户界面。 1.简单窗口 import sys from PyQt5.QtWidgets import QApplication, QMainWindow def main(): # 生成QApplication主程序 app = QApplication(sys.argv) # 生成窗口类实例 main_window =

.gitignore编写规则

常用规则 # 井号表示注释 # 忽略扩展名的文件 *.pyc *.processed # 忽略某些目录 /OracleImage/data/ # 忽略某些目录下的某种文件 /md5copy/**/*.PNG # 忽略任何.svn目录下的文件 **/.svn/   需要注意的是,如果某文件已经存在仓库中了,然后再把它写入.gitignore文件,这时候ignore是无效的,因为.gitignore只会去匹配Untracked Files。  

pymssql 2.1.4 ImportError: DLL load failed

最近有个工作需要用python读写sqlserver数据库,就用到了pymssql库。结果在离线的生产环境部署脚本的时候,发现报错: ImportError: DLL load failed: The specified module could not be found 查了下发现pymssql 2.1.4与2.1.2版本不再使用静态链接的方式包含freetds库,而是采用动态链接方式,需要另外下载并安装freetds。尤其是使用windows的whl离线安装包的时候。2.1.3与2.1.1版本则静态包含freetds。所以装回这两个版本即可。 参考: http://www.pymssql.org/en/stable/freetds.html#windows https://github.com/pymssql/pymssql/issues/399#issuecomment-185885836   另外,在使用的时候,发现一个问题。2.1.1版本的Cursor.execute(operation, params)函数的第二个参数不支持字典,只支持元组作为sql语句的参数。即:

windows文件夹右键菜单中添加“用Sublime打开”

在文件夹的右键菜单添加“用Sublime打开” 1、打开注册表编辑器regedit 2、找到HKEY_CLASSES_ROOT\Directory\shell,右键shell,选择新建项SublimeText3。 然后修改“默认”字符串的值为“Open in SublimeText3”(这是在右键菜单中显示的字符串) 然后新建字符串值Icon=C:\Program Files\Sublime Text 3\sublime_text.exe,0 (路径改为你的sublime程序路径,这是在右键菜单中显示sublime图标) 3、右键SublimeText3,在其下新建项Command,默认值为 C:\Program Files\Sublime Text 3\sublime_text.exe "%1" (同样路径要改成你的sublime程序路径) 大功告成:  

php木马

最近参加了一次网络攻防大赛的培训。学到了不少知识,挺好的。 php的一句话木马 <?php // 这是一个GET版本的木马 // 用法是 http://domain/cmdget.php?cmd=phpinfo();exit(); @eval($_GET['cmd']); ?> 上面这一句话就是一个php的木马。当然,木马的前提是要将这个php文件上传到你的web服务器中,并且可通过url访问才行。有很多web漏洞可能导致被上传木马,包括上传文件漏洞、sql漏洞等等。 解释一下上面这一句话: @符号,是php的错误控制符,放在任何表达式之前,该表达式可能产生的任何错误信息都被忽略掉。可以放可不放。 eval(code_str), eval函数把字符串参数code_str当作php代码来解析执行。 $_GET[‘cmd’]就很好解释了,就是获取url中的cmd查询字符串。 所以合起来的意思就是执行用户在url查询字符串cmd输入的语句。这个语句可以是任意合法的php语句。phpinfo(),exit()(加exit是因为有时候这一句话木马是注入到别的php文件里面的,为防止该文件的其他php语句打乱输出结果,直接执行完想要的命令就终止运行。)还有一个很重要的php语句system(cmd),可以执行系统指令,并输出结果。 所以,实用http://domain/cmdget.php?cmd=system(“ls -tl”);exit();就能得到在web服务器ls -tl命令同样的结果。这样就叫getShell了。

站内信的数据库设计

站内信现在几乎可以说是任何一套web系统的标配模块,那怎么样设计一个优雅的站内信模块呢。 首先,我们将站内信区分一下: 点到点:一对一发送的站内信,比如用户A发给用户B的消息,或者系统发给用户A的通知。type=private 点到多:一对多发送的站内信,接收对象较少,而且接收对象无特殊共性。可以当做私信。type=private 点到面:一对多发送的站内信,接收对象较多,而且接收对象同属于某用户组之类的共同属性。type=group 点到全部:一对多发送的站内信,接收对象为全部用户。通常为系统通知。type=global 一、用户量少 可以采用最简单的实现方式,只需要用到一张message表 不管是一对一的私信还是一对多的群发,每发给一个用户,就在表中插入一条数据,简单粗暴。 但是如果考虑到一对多的消息比较多的时候,消息的content字段其实是冗余的,可以将这张表拆成两份 二、拆分消息表 message表 message_content表 这样拆分后,对于一对一的私信,需要在message表与message_content表各插入一条数据。 对于一对多的消息,在message_content表只需要插入一条数据,大大节省了消息数据的存储空间。不过每发给一个用户,仍需要对应的在message表中插入一条数据。 再考虑一下,如果用户数量已经增长到百万级别,那么这个时候想要给所有用户发送一条全局系统通知,虽然说在message_content中只需要插入一条数据(type=global, sender_id=0),但message表中却仍要插入百万条数据,这个数据量是很可怕的。 三、用户量大 既然我们不希望因为一条系统广播而为每一个用户都在message表中插入一条数据。那么还有什么办法可以减少message表的存储量呢。不妨逆向思维一下,对于这种广播类的消息(type=group||global),并不是为每一个接收用户在message表中插入一条数据,而是只有当用户处理过该消息后(status=已读||删除)才将这一行插入message表。根据28原则,一个网站的活跃用户大概也就20%甚至更少。这样,只在message表中存储已处理的广播消息,能极大的减少存储空间。 所以,message与message_content表结构都不用变。

POST提交数据的方式

最近第一次使用vuejs做前端,用axios库来做表单的提交,结果发现php后台的$_POST是一个空数组,无法获取提交过来的数据。 查了一下,发现这个前端POST提交数据的方式有关。 1. 默认的application/x-www-form-urlencoded方式 使用html原生的<form>标签,并且不设置enctype属性,那么表单数据就会默认以application/x-www-form-urlencoded方式提交。 <form action="doAction.php" method="post"> 名字: <input type="text" name="fname"> <input type="submit" value="提交"> </form> 这时候可以看一下请求头的Content-Type: 这样,在php后台使用$_POST就能得到用户提交的表单数据。echo $_POST[‘fname’]; 另外如果使用传统jquery的$.ajax来提交form表单,默认也是以application/x-www-form-urlencoded方式来提交,所以使用$.ajax时候经常要将表单变量$(“#form_name”)序列化(serilize)

破解geetest的拖动验证码

最近有个项目需要爬取“国家企业信用信息公示系统”的数据,在该网站点击搜索按钮时,会弹出极验(geetest)的拖动式验证码。 遂一番google之,发现果然有哥们已经破解了这套验证码系统,甚至放出源码来了。学以致用。 原理很简单,首先定位缺口的位置,然后驱动浏览器将按钮移动到该位置。至于如何定位缺口位置,其实这个验证图是分上下两张的,底图是完整图,上一层则是有缺口的图,另外这两张图都是打散的,需要先还原出原图,然后再逐像素对比两张图片就可以得到缺口位置。移动按钮看似简单,但如果只是简单的将按钮设置到目标位置,极验后台会返回“怪物吃了拼图”,因为该验证码系统会将按钮的移动轨迹提交到极验后台,并验证该轨迹是否像一个人类的行为,所以我们需要尽可能模拟出人类的拖动行为。 代码示例: # -*- coding: utf-8 -*- import logging import time import random import re import requests import

Scroll to Top