存档

‘07 . 不上档的三流程序员’ 分类的存档

自己做了一个很猥琐的功能

2010年4月13日 Python

浏览器用 firefox,平时抓嵌入视频用 flashgot 插件,flashgot一般会调用系统中默认安装的下载工具

但是我不喜欢调用那些工具,而喜欢直接把地址抓出来后用 wget 下载,于是写了一段极简单的猥琐代码

  1. #!/usr/bin/env python
  2.  
  3. import os
  4. import sys
  5.  
  6. print "\n\n"
  7. print "   ",sys.argv[1]
  8. print "\n\n\t\tPress any key to exit."
  9. os.system(pause > NUL)

然后在 flashgot 里自己添加一下,就可以看到效果了

01

02

继续折腾:Rainlendar Lite 将Google Calendar

2010年3月3日 Python

之前已经实现了 Rainlendar Lite 远程同步 Google Canlendar :http://www.room702.cn/index.php/archives/411

但是若想实现自动化更新还要依靠 Windows 的计划任务,所以今天趁中午短暂的休息将这段代码改为 Windows 的服务

工作很简单,Windows 服务部分完全取自《Python Programming on Win32》书中的代码,这里需要做的仅仅是将之前的代码做些微调:

1、自动循环,每半个小时链接 Google Calendar 一次
2、工作目录修改为 C:\WINDOWS 目录,配置文件也丢到这里

脚本 PyRainlendarSvc.py 地址:http://www.room702.cn/tools/PyRainlendar/PyRainlendarSvc.py.txt

配置文件仍然没变,还是原来那个,只是建议里面指向的ics文件修改为绝对路径,如果不使用绝对路径,ics文件将下载到 C:\WINDOWS 目录,配置文件在这里:http://www.room702.cn/tools/PyRainlendar/PyRainlendar.ini

然后,准备安装:

1、注册 pythonservice.exe :

我使用 Python 2.5,安装 pywin32 后,改文件在 C:\Python25\Lib\site-packages\win32 中
执行命令:pythonservice.exe /register 即可完成注册

2、安装服务

把 PyRainlendarSvc.py 放到一个固定目录中,执行:python PyRainlendarSvc.py install

3、启动服务

执行命令:python PyRainlendarSvc.py start

然后到 services.msc 里将 PyRainlendarClt 服务设置为自动启动

完成后,到 Rainlendar 里将 ics 文件地址重新指向(这些可参考之前的BLOG),这样每隔两个小时 Rainlendar 会从 Google Calendar 更新一次数据

服务启动后,在任务管理器中看到的不是 PyRainlendarSvc 而是 pythonservices.exe ,占用资源不是很大,可以接受

svc1

svc2

一小段 python 代码:CLI_Progress_Bar.py

2010年1月15日 Python

从别的地方拆来的,原始地址忘记了 ……

import sys
import time
import math
 
# Output example: [=======   ] 75%
# width defines bar width
# percent defines current percentage
 
def progress(width, percent):
 
    
marks = math.floor(width * (percent / 100.0))
    
spaces = math.floor(width - marks)
    
loader = [' + ('=' * int(marks)) + (' ' * int(spaces)) + ']
    
sys.stdout.write("%s %d%%\r" % (loader, percent))
    
if percent >= 100:
        
sys.stdout.write("\n")
    
sys.stdout.flush()
 
# Simulate doing something…
for i in xrange(100):
    
progress(50, (i + 1)) # +1 because xrange is only 99
    
time.sleep(0.1) # Slow it down for demo

django 中的 alters_data

2009年11月24日 Python

加个开关控制 alters_data 的 True/False 切换

>>> class F:
…     var = 100
…     def t(self):
…        self.var = 200
…     t.alters_data = True

>>> m = Template(’Var = {{obj1.var}} , do it {{obj1.t}} , Var = {{obj1.var}}’)
>>> o = F()
>>> c = Context({’obj1′:o})
>>> m.render(c)
u’Var = 100 , do it  , Var = 100′
>>>
>>>
>>>
>>>
>>> oo = F()
>>> oo.t.__dict__['alters_data'] = False
>>> c = Context({’obj1′:oo})
>>> m.render(c)
u’Var = 100 , do it None , Var = 200′
>>>

【记录】让Perl的匹配不贪婪

2009年9月3日 Python

perl默认的匹配太贪婪了,今天做个自动分析脚本,匹配的内容总是多出来,最初脚本类似这样:

#!/usr/bin/perl

my $str = ‘AAA=”a1 a2 a3″  BBB=”b1 b2 b3″‘;
if ($str =~ /AAA=”(.*)”/){
print “AAA -> “,$1;
print “\n”;
}

只是想匹配到AAA中的内容,运行结果却是:AAA -> a1 a2 a3″  BBB=”b1 b2 b3

放狗得来的结果很简单,只要把量词改一下就可以了:

#!/usr/bin/perl

my $str = ‘AAA=”a1 a2 a3″  BBB=”b1 b2 b3″‘;
if ($str =~ /AAA=”(.*?)”/){
print “AAA -> “,$1;
print “\n”;
}

注意红色部分,执行结果是:AAA -> a1 a2 a3

这样就是我想要的了

解析 firefox 的 Bookmark

2009年8月28日 Python

因为家里有多台电脑,所以一直想弄个脚本来做firefox的书签检查,主要是定期检查每台电脑之间的书签分别发生了什么样的变化,以便及时更新和统一书签,也防止一些书签误删

不过做这个的第一步就是要解析firefox的书签,firefox的大部分内容都是通过sqlite来存储的,还算比较容易,sqlite文件在firefox的profiles文件夹中,一般路径是在 %APPDATA%MozillaFirefoxProfiles 目录下有个以default结尾的目录,目录中会有多个sqlite文件,其中 places.sqlite 是最重要的,书签以及访问历史记录都存储在这里

书签不是直接存储在一个特定表里,而是分别在 moz_bookmarks 和 moz_places 两个表中,moz_places中记录了书签还有所有访问过的地址,而moz_bookmarks只是记录了一些书签的id(在moz_bookmarks中体现为 fk 列) 和 书签的名字(moz_bookmarks中体现为title列),而moz_bookmarks 的fk 列 和 moz_places 中的 id 列是对应的,而moz_places 中的 url 列又记录了所有的地址,因此,就有这样的对应关系:

moz_bookmarks 中 :fk —> tilte  ,moz_places中: id —> url ,同时:fk == id ,即,两张表通过fk和id来建立联系

当然,除了这些之外,如果需要查找上级目录的话(firefox标签中的目录),还需要考虑到其他列,在这里先把最简单的对应关系搞清楚,其他的以后慢慢再研究了

列出全部书签的id、title和url的代码如下,这里考虑到一些特殊字符的原因,所以title需要用utf-8输出,而Windows的命令行不支持utf-8,所以会看到乱码,不过后期会考虑保存成excel或是xml文件以方便比对,所以这里可以先忽略这个编码问题了 ……

#!/usr/bin/env python
# encoding = gbk
# Python[AT]Live.it
 
import os
import sys
import codecs
import sqlite3
 
#moz_places = ‘places.sqlite’
moz_profile = os.getenv(appdata) + \Mozilla\Firefox\Profiles
profiles_dir = os.listdir(moz_profile)
 
if 1 == len(profiles_dir):
    
moz_places = moz_profile + \’ + profiles_dir[0] + \places.sqlite
 
else:
    print "There are more than one directories in :"
    print "t%sn" %moz_profile
    c = 1
    for i in profiles_dir:
        print "[%d] %s
\%s" %( c , moz_profile , i )
        c = c+1
    print "n"
 
    try:
        idx = raw_input("Choooooooooose : ")
    except KeyboardInterrupt:
        print "terminated by user !"
        sys.exit(0)
    try:
        idx = int( idx.strip() )
    except ValueError:
        print "Error …"
        sys.exit(1)
 
    moz_places = moz_profile +
\ + profiles_dir[idx-1] + \places.sqlite
    print "n"
    #sys.exit(0)
 
if os.path.exists(moz_places):
    pass
 
else:
    print "Can not locate the profilesnt%snt I am dying …" %moz_places
    sys.exit(1)
 
db = sqlite3.connect( moz_places )
cur = db.cursor()
 
# urls
try:
    cur.execute("select id,url from moz_places")
 
except sqlite3.OperationalError:
    print "Database maybe locked , Please shutdown the Firefox browser first."
    sys.exit(1)
 
urls = cur.fetchall()
 
url_dict = {}
for url in urls:
    if None not in url:
        url_dict[ url[0] ] = str( url[1] )
 
# titles
cur.execute("select fk,title from moz_bookmarks")
titles = cur.fetchall()
 
for item in titles:
    if None not in item:
        print "id = %s , title = %s , url = %s " %(item[0] , item[1].encode("utf-8") , url_dict[item[0]])
 
db.close()
# E_O_F

执行截图

out

Python异常:too many file descriptors in select()

2009年8月27日 Python

Twisted.Network.Programming.Essentials 第二章中的portscan.py 完成了一个端口扫描的功能

代码portscan.py

#!/usr/bin/env python
# Example 2-5
# portscan.py
 
from twisted.internet import reactor, defer
from connectiontest import testConnect
 
def handleAllResults(results, ports):
#    print results[0]
    
for port, resultInfo in zip(ports, results):
 
        
success, result = resultInfo
        
if success:
            
print "Connected to port %i" % port
    
reactor.stop( )
 
import sys
 
host = sys.argv[1]
ports = range(1, 201)
testers = [testConnect(host, port) for port in ports]
defer.DeferredList(testers, consumeErrors=True).addCallback( handleAllResults , ports )
 
reactor.run( )

代码connectiontest.py

#!/usr/bin/env python
# Example 2-4
# connectiontest.py
 
from twisted.internet import reactor, defer, protocol
 
class CallbackAndDisconnectProtocol(protocol.Protocol):
 
    
def connectionMade(self):
 
        
self.factory.deferred.callback("Connected!")
        
self.transport.loseConnection( )
 
class ConnectionTestFactory(protocol.ClientFactory):
 
    
protocol = CallbackAndDisconnectProtocol
 
    
def __init__(self):
 
        
self.deferred = defer.Deferred( )
 
    
def clientConnectionFailed(self, connector, reason):
 
        
self.deferred.errback(reason)
 
def testConnect(host, port):
 
    
testFactory = ConnectionTestFactory( )
    
reactor.connectTCP(host, port, testFactory)
    
return testFactory.deferred
 
def handleSuccess(result, port):
 
    
print "Connected to port %i" % port
    
reactor.stop( )
 
def handleFailure(failure, port):
 
    
print "Error connecting to port %i: %s" % ( portfailure.getErrorMessage( ) )
    
reactor.stop( )
 
 
if __name__ == "__main__":
 
    
import sys
    
if not len(sys.argv) == 3:
        
print "Usage: connectiontest.py host port"
        
sys.exit(1)
 
    
host = sys.argv[1]
    
port = int(sys.argv[2])
    
connecting = testConnect(host, port)
    
connecting.addCallback(handleSuccess, port)
    
connecting.addErrback(handleFailure, port)
    
reactor.run( )

但是当修改 ports = range(1, 201) 为 ports = range(1, 513) 甚至修改为更大的值时,会出现一个异常:exceptions.ValueError: too many file descriptors in select()

引起异常的原因是由于 Windows 对文件描述符有一定限制,这个限制值是 512 ,而在 Linux 下这个限制为 32767
如果超过这个限制值,就会出现类似上面的异常

关于文件描述符(file descriptor)可参考:http://en.wikipedia.org/wiki/File_descriptor

又一只 python 爬虫

2009年8月20日 Python

比之前那个python爬虫简单
简单看了下效果,简单工作应该能应付,还没仔细看代码

sSpider.py.tgz

python 爬虫

2009年8月18日 Python

一只python写的爬虫,以前收集的,好像是来自pypi,还不错

还有几只强大的爬虫,不太容易驾驭,用这个相对简单好用,支持的爬行方式和内容也不少

下载 spider.py.gz

>>> import spider
>>> spider.webspider(b=’http://www.sohu.com’,w=20,d=1,t=10)
(['index.html', 'sohuflash_1.js'], ['http://www.sohu.com/', 'http://www.sohu.com/sohuflash_1.js'])

python SimpleHTTPServer

2009年7月20日 Python
import sys
import SocketServer
import SimpleHTTPServer
 
httPort = 8000
try:
    
httPort = sys.argv[1]
    
httPort = httPort.strip()
    
httPort = int(httPort)
except IndexError:
    
pass
 
httpHandler = SimpleHTTPServer.SimpleHTTPRequestHandler
httpDaemon = SocketServer.TCPServer( ( "", httPort ) , httpHandler )# bind port on all interfaces
 
print "Listening on Port",httPort ,""
if 8000 == httPort:
    
print "Starting httpd on a different port number : python %s port-number" %sys.argv[0]
print "Press Ctrl-C to terminate httpd."
try:
    
httpDaemon.serve_forever()
except KeyboardInterrupt:
    
print "\n\npyhttpd has been terminated !\n"
    
sys.exit(0)