17年11份离职后在在调养身体时写的一些小工具


头条视频采集

开发语言:  python

适用平台:  windows, linux, macos

详细地址: http://caipiao365.vip/article/11

时间同步助手  

开发语言:  C++ 

适用平台: windows (xp及其以上的系统)

老电脑的福音, cmos电池没电的笔记本.主板系统时钟坏的的电脑可以用这个时间同步工具.

详细地址: http://caipiao365.vip/article/MyTime


开关机助手:

开发语言:  C++ , java

适用平台:  windows, android

懒人福利,想想在大冬天躺在被窝里看电影,看完后不想起来去关机是多么痛苦的一件事.想想本来家里的电脑是开这的,有时候因为有点事出去了一下,就忙忘记关机了.就想要是在手机上可以关闭该多好呀.所以这个软件就产生了.

详细地址: http://caipiao365.vip/CloseAssistant


关机助手电脑端设置说明

 安装服务   把本程序注册成windows服务程序

 删除服务   从windows服务中删除本程序

启动服务   安装成功后,从windows服务中启动本程序   

关闭服务    从windows服务中停止本程序  


记录信息和错误      记录程序运行生成的调试信息和错误信息   

只记录错误             只记录程序运行产生的错误信息

不记录日志             不记录任何日志

UDP端口               手机端UDP广播扫描PC端的UDP的端口,默认是8910,不要设置冲突的 


本机备注: 在手机上查看的计算机备注

内网开机端口:  局域网唤醒的 端口地址,默认是9.

外网地址:         这个是您家里路由器的动态域名

外网开机端口:  这个是您从外面如(手机网络,不是自家里的wifi)唤醒(打开)你家电脑的端口

外网关断端口:  这个是您从外面如(手机网络,不是自家里的wifi)关闭你家电脑的端口

外网相关的设置具体看: http://caipiao365.vip/article/19


**电脑端改了后,手机端口也要修改 电脑端修改后要重启一下服务使配置文件生效**  

手机端软件的设置


安装后打开手机app界面如下

刷新 按钮 的功能是手动刷新 当前局域网中的计算机开关机状态 (应为广域网和自动刷新的功能还没有做好)

内网: 默认是内网  在点一下就是外网 (选择当前操作是 内网开关机 还是外网)

点左上面的 按钮打开菜单 如下界面


点击设置打开系统全局设置界面 如:


UDP扫描断口: 和PC端要一致, 其他的设置暂时保留,自动刷新功能要用到的.





要想在使关机助手来打开电脑先要在bios里设置 一下.

具体进BIOS的方法 稍微有些不一样,但都是在开机的时候(显示黑屏的状态下)一直按一个键.有的在开机时有提示;

不过一般都是按 del键或者是 esc 还有的可能是 F11  F12.自己 看开机提示.或者自己 去网上搜一下看自己 的主板按什么键进bios.

进入BIOS后找到 Wake on LAN 这个选项 启用他 (把disabled改成enabled)就可以了,如下图:

 Wake on LAN 这个选项不同的主板(BIOS)所在的位置不太一样,具体自己去网上搜一下.

在BIOS启用 Wake on LAN 后进入Windows系统后还要设置一个地方.

1.打开 控制面板 ==> 网络和 Internet ==>网络连接  如下图:


2.双击你的 插网线的网卡打开 网卡 状态对话框  

注意要是用的是无线网卡, 有的无线网卡也支持局域网唤醒功能,在BIOS里设置就是不 Wake on WLAN  了 而是 Wake on WLAN , 那么在这一步就选择的网卡是你的无线网卡了.

3. 点击左下面的 属性(P) 按钮  打开网卡属性对话框:   

4.点击 配置(C) 按钮 打开 网卡属性 对话框 选择 电源管理 标签


把这个界面上的复选框 全勾上 然后点 确定 按钮, 关闭所有的对话框. 到此开机设置完毕. 

写在前面的话

从去年离职回家到现在也有一段时间了,曾经到昨天为止问过我有关这个问题的朋友有很多,索性今天写篇文档记录一下.省得下次还有朋友问题这样的问题.或者避免还有朋友可能会出现这样的问题.让朋友做到提前预防的目的.从而做到减少重要文件(数据)丢失的损失.现在就索性整理几篇文章来特别说明一下.下次碰到了就直接发链接就可以了.

特别说明

A.    下面的讨论的系统都是在windows系统上(XP和XP以上的系统)

B.     在没有特别的说明下只本文只讨论硬盘的问题和常规保养以及提前预防和备份数据

C.    不讨论在病毒或者木马或者安装了不兼容的软件(驱动).或者软件(驱动)冲突造成的情况下造成的一些怪异类似硬盘问题的问题.

D.    硬盘的日常保养说的是机械硬盘 (用SSD的土豪请饶开)

E.    电脑(计算机)是非常非常非常笨的一种电器


不废话先上干货


    1.先废话机械硬盘变拖慢电脑产生的原因之-----碎片产生来龙去脉(啰嗦的直接跳过)

应该用过电脑的朋友都会在抱怨说我的电脑用了一段时间越来越慢了.因为我身边就有好多朋友在抱怨这个问题.当然造成电脑运行慢的原因有非常多.但是在这里我只讨论和分析一下硬盘造成电脑运行慢的问题.

硬盘的主要功能就是保存数据(各种文件)的.文件有一个重要的指标就是size(大小).在这里我们先简单的啰嗦下.一块新硬盘电脑是无法使用的.要使用的话我们先要给这块新硬盘做两个操作:

a.     分区  

先我们把一块新硬盘看作是一张很大的白纸.分区就相当于要把这张白纸装订成多少个本子,每个本子的尺寸(大小,如 A4 A5 B5 A6 A3)也就是你看到 我的电脑(计算机) 里有多少个盘(如 C盘 D盘等), 每个盘的大小(如多少G).

b.  格式化  

一块新硬盘分区后还要做的一个动作就是格式化 格式化就是来把装订成的本子就成什么样的本子.如 横格 竖格 网格 格子 方格 田子等(win硬盘分区的格式有 FAT  EXFAT  FAT32  NTFS 常见的是 NTFS)

                   一块新硬盘做了上面两个动作后就可以用了.但是电脑是很笨的.如要是要格式化的时候你把设置的是格子本.这样的话分区所有的格子的大小是一样的(一个格子本的整本的格子大小是一样的).这样我们要向分区里写数据(文件)的话就像在格子本上写字一样.但是文件有大小的.要是文件巧合可以在一个格子里写完就只占一个格子的地方.但是非常多的情况是要几个甚至几十 几百或更多的格子去写(当然你要是用圆珠笔这样的笔在格子本上写,写完了这个本子只能看了,正常情况下是不能在写的了.这样的存储装置在电脑上叫只读存储ROM,这样的本子(存储)只能写一次可以读多次,但是我们的硬盘不是这样的,就好比是用铅笔在格子本上写字).要是有时你觉得有一段话(文件)没有用了,你就用橡皮擦擦了(把文件删除)请注意了,硬盘造成电脑慢的原因就要出来了.您在看看,电脑你保存文件电脑就在空白的格子上写数据,你删除文件电脑就在这个文件对应的格子上擦除这些格子就成空白的(目前就这么理解吧,其实擦除你也知道很费时间的,电脑再笨也不会这么干,这里非常重要涉及到后面的数据恢复)想想你要是在电脑上频繁的删除文件写文件.会造成什么可的情况呢.就是会如一个文件可能会保存在这个本子(分区)的不同是页码(区域)中.当你在去看(读)这个文件时就要来回翻好多好多遍.(机械硬盘的原理不多说,但是他在分区的不同区域去读数据比在一个本子上翻页找文字还要慢NN倍) 这样的话相信聪明的您就明白你的电脑为什么会在没有安装什么新的软件,而且没有中毒,也没有上什么不可描述的网站后还会变慢了吧.

 

机械硬盘的保养之-------碎片的优化

      在上面啰嗦了一大堆后.聪明的你也许就会想到要是能有一个工具可以定期去把分散的文件整理到一起就可以了.其实这样的工具MS早就提供了.在要整理的磁盘分区点 右键 à属性打属性对话框点开工具标签如下图:


然后点 优化(O) 按钮 打开 windows 磁盘整理工具如下图:

看到这里聪明的看官肯定就知道要整理那个分区, 就点先选那个分区选中他然后点 优化(O) 按钮

这里是MS给WIN系统自带的磁盘优化工具.但是个人推荐一个很优秀的工具(我从XP用到了WIN10).这个软件叫Smart Defrag,软件如下:

 

这个软件还可以设置成定时任务去自动整理您电脑上的碎片.


2.防患于未然之-------给硬盘做体检

       平均每年至少有5次有朋友问我硬盘的数据怎么恢复.自己也碰见过.曾经在公司工作,辛辛苦苦加班加点写了一周的源码.没有提交到SVN上,在一个周一的上午一开机硬盘给我来了个罢工.害得自己又加班加点去写编码.所以在自己和身边朋友的一次次的血的教训下(有几次朋友问题的是服务器的磁盘挂了如何恢复).把自己的经验记下来,希望能帮助到大家.

机械硬盘的理论寿命是3万小时以上,但是硬盘的容量越大寿命就越短,还就是PC硬盘的制作工艺和服务器的硬盘的制作工艺有很大的差别(毕竟价格就摆在那里相差这么大).  还有就是万一硬盘坏了.在质保期内厂家都是给你换新的.(不要觉得是件好事.有时候数据比硬盘要贵N次方,我曾经买了一个2T的移动硬盘,辛辛苦苦把自己的重要资料复制进去加上整理,一共花了几天几夜.结果两个多月坏了,我寄到售后去,结果那边二话不说给我邮一个新的回来.各位能想想我收到货的那时候的心情吗.幸好自己有重要数据保存多份的习惯).好了废话不多说了.先上图

当您看到上面三张图片的时个你就会建议我 把 一个300G的和一个500G的这两个硬盘的重要数据做备份了吧.应为这两次硬盘已经开始有严重的错误.天知道他什么时候来个罢工.

看到这里聪明的看倌朋友您应该知道了吧

 1.电脑的硬盘要定期做一下磁盘碎片整理

 2.重要的数据最好保存多份(鸡蛋不能放在同一个篮子里)

 3.定期用HDTune这样的软件来检查一下硬盘的健康度.在适当的情况下可以考虑淘汰问题严重的硬盘.

 4.最好不要用电脑的重启功能.如果要重启的话建议先关机,等电脑的电源彻底关闭后.停顿15到30秒左右在开机.


夜深了祝各位朋友晚安.还有下面两篇明天贴上

个人电脑数据的安全防护之------<可恶的坏道你给我滚>

个人电脑数据的安全防护之------<闲话数据恢复>


    孩子特喜欢跳舞,以前下的视频看了好次了.想换短一点的新一点的视频.做为一个10多年的码农.是不可能手动一个个文件去下载的.当然想要一个方便的方法去下载自己想要的视频了.所以就想到了python.因为python在这方面有天生的优势.好了废话不多说先上几张图片看看效果.

下面言归正传来谈谈具体的细节。

第一步 我们打开 https://www.toutiao.com/ 搜素关键词 如 儿童舞蹈 

第二步 打开  开发者工具  把搜索结果页面移动到 最下面 就会看到有 ?offset=20&format=json......这样的连接  如下图片

通过分析发现 这个连接是用来异步获取搜索结果的具体参数如说明如下:

            "offset": nPages,             #记录的开始数字 0开始  0 20 40 60 具体见 count 字段  默认是每页有20条记录但是每面多多少少有些广告

           "format": "json",             #返回的数据类型

           "keyword": serchStr,          #要搜索的关键词

           "autoload": "true",           #html网页获取记录后是否自动显示的页面里

           "count": "20",                #每次请求返回的记录大小(建议和前台的页面保持一致) 我设置其他的,他们的的服务器也只每次返回20条记录

           "cur_tab": "2",               #前面页面的标签(可以用2不用管他 和前台的页面保持一致)

           "from": "search_tab",         #提交搜索的前面页面的表单名(不用管他就用这个 也就是cur_tab 2)

           "callback": JSARRNAME         #Json数据返回后前台页面JS代码里数组的名字这个我改了一个 他的太长了点 看不习惯 @_@

          这个说明具体见 net\DownVideo.py里的 DownVideoMgr类的GetParas方法

然后在看一下这个连接返回的数据:

当时一看乐了,是mp4的地址,这不是非常非常简单吗.从网上用python下个文件就几行代码的事情.这样的话就非常快速的加上了下载文件的方法:

class VideoItem(object):
    #视频的标题
    title = ""
    #视频的URL  
    url   = "" 
    #初始化方法
    # _title 视频的标题
    # _url   视频的地址    
    def __init__(self, _title, _url):
        self.title = _title
        self.url = _url

class DownVideoMgr(object):
     #根据url保存文件
    #参数:
    #       url      mp4文件的URL 
    #       loactFile   本地保存的路径
    #返回值:
    #        True    下载成功
    #        False    下载失败
    def SaveUrl2File(self, url, loactFile):  
        bRet = True
        try:
            request = urllib2.Request(url, headers=headers)
            response = urllib2.urlopen(request) 
            data = response.read() 
            with open(loactFile, "wb") as code:   
                code.write(data) 
        except Exception as e:
            print e
            bRet = False
        return bRet

然后当时就想在写个写一个获取页面JSON返回的视频记录数据的方法然后就完成了.想到了就一鼓作气继续写了下面这几个方法:

   #获取打开页面的结果
    #参数:
    #       url  打开网页的地址 
    #返回值:
    #       成功 打开页面的结果
    #       失败 空字符串
    def GetWebRet(self, url):
        htmlStr = ""
        try:
            request = urllib2.Request(url, headers=headers)
            response = urllib2.urlopen(request)
            htmlStr = response.read()
        except Exception as e:
            print e
            bRet = False
            htmlStr = ""
        return htmlStr

    #获取搜索的结果
    #参数:
    #       seachKey  搜索的关键词 
    #       nPage     第几页
    #返回值:
    #       成功 搜索的JSON结果
    #       失败 空字符串
    def GetSeachRet(self, seachKey, nPage):        
        url = httpBase + self.GetParas(seachKey, nPage)
        jsonStr = self.GetWebRet(url)
        if (len(jsonStr) > 10):
            jsonStr = jsonStr[len(JSARRNAME) + 1:-1]
        return jsonStr

#根据KEY返回JSON对象的里值
    # jsObj json对象
    # key   json对象的key    
    #参数:
    #       jsObj json对象
    #       key   json对象的key
    #返回值:
    #       成功 要是KEY存在就返回对应的值
    #       失败 要是KEY不存在返回空字符串
    def GetJsonItemData(self, jsObj, key):
        if jsObj.has_key(key):
            return jsObj[key]
        return ''


    #根据JSON字符串获取视频记录信息
    #参数:
    #       jsonStr json字符串    
    #返回值:
    #       VideoItem  列表
    def GetVItem(self, jsonStr):
        jsObj = json.loads(jsonStr)
        itemsize = len(jsObj['data'])
        videoList = []
        for i in range(0, itemsize): 
            tmpJs = jsObj['data'][i]
            #.decode('raw_unicode-escape').encode('utf-8')
            title = u"" + self.GetJsonItemData(tmpJs, 'title')
            url = u"" +  self.GetJsonItemData(tmpJs, 'url')
            if url.find("wukong.com/question") > 0:
                url = ""

            if len(title) > 0 and len(url) > 0 :
                tItem = VideoItem(title, url)
                videoList.append(tItem);
        return videoList

    #获取搜索的结果
    #参数:
    #       seachKey  搜索的关键词 
    #       nStart    从第几条记录开始获取
    #返回值:
    #        VideoItem  列表  
    def GetVideoItem(self, seachKey, nStart):
        jsonStr = self.GetSeachRet(seachKey, nStart)
        return self.GetVItem(jsonStr)

写到这里心里想现在就差一个主方法了,然后开打电脑放这里让他自动下载.我可以关闭显示器睡觉去了.当时想想就心里乐开了.马上加了个非常简单的方法如:

    #根据VideoItem下载视频
    #参数:
    #       vItem    流媒体信息
    #       可以通过 GetVideoItem 方法获取
    #返回值:
    #        True    下载成功
    #        False    下载失败 
    def DownVideoItem(self, vItem):
        fileSavePaht = self.sBaseFilePath + vItem.title.encode("gbk") + ".mp4"
        if os.path.exists(fileSavePaht):
            if self.isFileOver:
                try:
                    os.remove(fileSavePaht)
                except Exception as e:
                    print e
                    return False
            else:
                return True 
        return self.SaveUrl2File(vItem.url, fileSavePaht) 

        
def Test(): 
    DowObj  = DownVideoMgr()    
    keyS = "儿童舞蹈教学"
    vArrList = []
    for i in range(0, 201, 20):
        vItem = DowObj.GetVideoItem(keyS, i) 
        for r in vItem :
            vArrList.append(r)  

    for r in vArrList :
        DowObj.DownVideoItem(r)

if __name__ == '__main__':
    Test()

写到这里然后高高兴兴的打开cmd 执行了 python xxxx.py  结果才发现是我高兴的太早了 以mp4结尾的文件有,但是更多的是流媒体格式的.

如:

title:"儿童舞蹈《爵士girl》"

url:"http://toutiao.com/group/6528510675289899527/"

然后打开下面这个url 一看视频是可以播放的.继续按F12 有video标签如 下图片:


里面有src属性,打开这个src属性一看是流媒体的地址,用这个地址可以用上面的SaveUrl2File 方法下载.一看又来劲了(当时的心情比吃NNN条 士**架 还有劲)

这样是不是打开 打开前面获取里的 http://toutiao.com/group/6528510675289899527/ 这个URL页面就可以获取到这个 video 标签里的属性吗? 不就是在加一个流程的事情吗,easy.

GetWebRet 这个方法上面早就写好了 我就直接用就可了.

然后写了个小测试程序如下:

dObj  = DownVideoMgr()
htmlStr = dObj.GetWebRet("http://toutiao.com/group/6528510675289899527/")
nStart = htmlStr.find("video")
print nStart

结果一运行 输出-1  我以为夜深了我眼睛太累了就搽了一下眼睛检查了几次代码在执行,结果死活还是-1.我想这不是我程序的问题吧.应该是那个页面的问题,这个video标签是JS动态生成的.然后就打开那个页面点右键查看源码.

果然是JS动态生成的.想算了.懒得分析JS了.但是又想一下前面写了这么多,费了这么多时间和精力现在放弃对不起孩子渴望看舞蹈视频的那种眼神.然后就继续分析这个页面和里面的JS代码加引用的JS文件.然后在眼睛上抹了几次的清凉油的结果下终于找到下面这一段JS,在http://s3.pstatp.com/tt_player/player/tt2-player.js这个脚本文件里(注JS给我格式化了.原页面里的JS压缩了没有换行):+

分析这段JS源码后加了下面几个方法和修改了部分方法

    #根据流媒体的网页地址获取流媒体的srcID
    #参数:
    #       url     流媒体的网页地址
    #返回值:
    #        True    返回流媒体的src
    #        False   返回空字符串
    def GetStreamingVideoID(self, url):
        htmlStr = self.GetWebRet(url)
        if len(htmlStr) < 5: -1=""> 0:
            nEnd = htmlStr.find(",", nStart) 

        if nEnd > 10: 
            strID = htmlStr[nStart+len(strFindSrart)+2 : nEnd-1]         
        
        return strID
        

    #获取随机数    
    #参数: 无 
    #返回值:
    #        随机数字符串
    def GetRandPara(self):
        randStr = bytes(random.random()) [2:]
        return randStr

    #获取CRC检验右移的值  
    #参数:
    #       val    右移的值 
    #        n     右移的值的位数
    #返回值:
    #         右移动的结果
    def GetCrcValue(self, val, n):
        return val >> n if val >= 0 else (val + 0x100000000) >> n

 
    #根据视频的ID获取真实播放地址的API地址
    #参数:
    #       vID        流媒体的ID 
    #       vID 可以通过 GetStreamingVideoID 这个方法获取
    #返回值:
    #        获取真实播放地址的API地址
    def GetStreamAPIUrl(self, vID):
        r = self.GetRandPara()   
        jsUrl = 'http://i.snssdk.com/video/urls/v/1/toutiao/mp4/%s' % vID 
        n = urlparse.urlparse(jsUrl).path + '?r=' + r 
        c = binascii.crc32(n)  
        s = self.GetCrcValue(c, 0)

        return jsUrl + '?r=' + r + '&s=' + bytes(s)

    # 获取真实播放地址的API获取真实的流媒体播放地址
    #参数:
    #       url        流媒体的获取API的地址
    #       url 可以通过 GetStreamAPIUrl 这个方法获取
    
    #返回值:
    #        True    流媒体真实地址
    #        False    空字符串
    def GetStreamSrc(self, url):
        vID = self.GetStreamingVideoID(url)
        src = self.GetStreamAPIUrl(vID)
        jsonStr = self.GetWebRet(src)
		
        vUrl = ""
        strFindSrart = "main_url" 
        nStart = jsonStr.find(strFindSrart) 

        nEnd = -1
        if nStart > 0:
            nEnd = jsonStr.find(",", nStart)

        if nEnd > 10: 
            vUrl = jsonStr[nStart+len(strFindSrart)+2 : nEnd-1]         
        
        videourl = base64.b64decode(vUrl)
        return videourl

    #根据流媒体的地址下载流媒体文件
    #参数:
    #       url        流媒体的Src地址
    #       file     本地保存的路径
    #返回值:
    #        True    下载成功
    #        False    下载失败 
    def DownStreamVideo(self, url, file):
        videoUrl = self.GetStreamSrc(url)
        return self.SaveUrl2File(videoUrl, file)

    #根据VideoItem下载视频
    #参数:
    #       vItem    流媒体信息
    #       可以通过 GetVideoItem 方法获取
    #返回值:
    #        True    下载成功
    #        False    下载失败 
    def DownVideoItem(self, vItem):
        fileSavePaht = self.sBaseFilePath + vItem.title.encode("gbk") + ".mp4"
        if os.path.exists(fileSavePaht):
            if self.isFileOver:
                try:
                    os.remove(fileSavePaht)
                except Exception as e:
                    print e
                    return False
            else:
                return True 

        if vItem.IsMp4(): 
            return self.SaveUrl2File(vItem.url, fileSavePaht)
        else: 
            return  self.DownStreamVideo(vItem.url, fileSavePaht)

到这步了 采集的功能基本上完成了,但是想到要是有个界面可以给我父母也可以找一些视频下载下来给我孩子看也是件美事(考虑到我这个民工不在家的时候,下载的视频孩子看厌烦了要换新的)

然后就用wx做了个简单的界面

就是上面的图片里的界面

详细源码见:  gitee