可可熊的窝

Category Archives: Python

更新PyFetion && getsong

IN:Python   Tags: , ,    Comments:8

给PyFetion加入了HTTP代理的支持,HTTP发送方式中。TCP发送方式也可能会加上吧,使用SocksiPy这个库吧,有时间再说。

改PyFetion的时候发现urllib2的一个问题:
先看下面这段代码:

import urllib2
headers = [("Content-Type","application/oct-stream"),]
opener = urllib2.build_opener()
opener.addheaders = headers
urllib2.install_opener(opener)
print "after install_opener"

ret = opener.open('http://www.dict.cn',data="word=ss")
print ret.read()

抓包发现发送的内容为:

POST / HTTP/1.1
Accept-Encoding: identity
Content-Length: 7
Host: www.dict.cn
Content-Type: application/x-www-form-urlencoded
Connection: close

word=ss

这里我在代码里已经指定了HTTP的header: Content-Type,但是发出去的时候却被改变了。

通过分析urllib2的代码,找到:

if request.has_data():  # POST
    data = request.get_data()
    if not request.has_header('Content-type'):
        request.add_unredirected_header(
            'Content-type',
            'application/x-www-form-urlencoded')
    if not request.has_header('Content-length'):
         request.add_unredirected_header(
           'Content-length', '%d' % len(data))

scheme, sel = splittype(request.get_selector())
sel_host, sel_path = splithost(sel)
if not request.has_header('Host'):
    request.add_unredirected_header('Host', sel_host
    or host)
    for name, value in self.parent.addheaders:
    #这里的parent是opener对象
    name = name.capitalize()
    if not request.has_header(name):
        request.add_unredirected_header(name, value)

urllib2发现如果是POST数据的话自己添加了Content-Type,接着才去追加opener对象中的headers,这时已经有Content-Type了,所以opener对象增加的Content-Type就无效了。

解决办法是创建request对象,在request对象中设置Content-Type:

request = urllib2.Request(url,headers=headers,data=body)

不知道是上面的示例代码写法不规范呢?还是算Python的一个小问题呢?

最近发现周董的不少歌挺好听,于是找个脚本来下载周董的歌(从百度mp3中), getsong就进入了眼的视野,不过不支持下载某个歌手的全部歌曲,俺自己加上去,正在下载周董的歌:

[cocobear@cocobear getsong]$ ./getsong.py -a 周杰伦
正在下载第1首(共104首) 歌手:周杰伦 曲名:她的睫毛
已经成功下载《周杰伦 – 她的睫毛》
…….

不过这会儿断了,getsong好像又有bug了,今天就不折腾了,明天再整整吧,看书,睡觉了。

03-24
2009

更新两个小脚本

IN:Python   Tags: , ,    Comments:4

一个是以前写的导出抓虾收藏的工具,增加了保存抓虾上文章的功能,因为只导出链接有些文章地址可能已经失效。

另一个就是pysdcv,前面文章介绍过了,整理了一下,测试了一下,然后放在了google code上面,直接使用星际译王的词典,查一个单词大概0.15秒的时间:

cocobear@0-0 /home/cocobear/Work/pytool/pysdcv $ make
gcc lookup.c -g -I/usr/include/python2.5 -lz -shared -fPIC -o lookup.so
cocobear@0-0 /home/cocobear/Work/pytool/pysdcv $ time ./pysdcv.py test
*[test]
n. 测试, 试验, 化验, 检验, 考验, 甲壳
vt. 测试, 试验, 化验
vi. 接受测验, 进行测试
【医】 试验, 测验
【经】 检验, 试验, 测试
相关词组:
put sth to the test
stand the test
give a test
take a test
test sb’s ability

real 0m0.164s
user 0m0.143s
sys 0m0.010s

如果是未使用gzip压缩过的dict文件,则0.05秒左右。

03-20
2009

用Python QQ写一个挂QQ工具

IN:Python   Tags: ,    Comments:10

Python QQ是好早以前就有的一个项目,不过因为很久没更新过,以前看到的时候不能登录,所以没怎么关注过,最近代码被开发者放在了google code上面,也做了些改动,目前可以登录,发送,接收消息了,不过不是很稳定。最近看了看这个项目的代码,对整个socket-qq分枝有了全面了解。在代码设计上也学到了不了东西:-)

Python QQ是在Windows上面开发的,所以我在Linux下测试的时候还有不少问题,最近改了改,然后做了个挂QQ的工具给草儿同学,很不完善的,也很不稳定,使用wxPython+threading完成,GUI+多线程确实是很折腾人的,在多线程更新GUI上使用了wx.CallAfter函数,可以查看limodou博客的介绍。

截个图上来:
oqq

先不发布了,继续完善Python QQ。

03-19
2009

发一个Python版的星际译王

IN:C, Python, 编程相关   Tags: ,    Comments:3

sdcv-0.4.2版本的代码有3480行,而图形界面的星际译王更是有N多的代码,俺也写了一个就十几行的Python代码,速度当然比不上sdcv,能差十倍,不过,请注意,sdcv查一个单词是0.01秒,我这个是0.1秒,我不觉得有人能感觉出来差别。

其实我的核心是C语言写的,之所以在速度上没有sdcv快是没有做那么些优化,俺只写了80多行,而且还有不少代码是用作Python封装的。我以前写文章说过sdcv代码写的很麻烦,用C语言可以很简洁的写出来,现在确实做到了,只是结合了Python。我觉得这种模式挺不错,影响速度的核心使用C语言去写,然后主逻辑框架使用Python写,不仅效率不会受影响,开发的速度也提高了不少。(我这个例子Python并没做什么)

static PyObject * lookup(PyObject *self, PyObject *args)
{
    int fd;
    char *file_prefix;
    long file_size;
    long wc;
    char *word;

    char *data;
    const char *p;
    long index_size;
    int offset;
    int size;
    int flag = 0;
    unsigned char *buf;

    if (!PyArg_ParseTuple(args, "slls:lookup",
                &file_prefix, &file_size, &wc, &word)) {
        return NULL;
    }
    char file_name[256];
    strcpy(file_name, file_prefix);
    strcat(file_name, ".idx");
    if ((fd = open(file_name, O_RDONLY)) < 0) {
        printf("open failedn");
        return NULL;
    }
    data = (char *)mmap( NULL, file_size, PROT_READ, MAP_SHARED, fd, 0);
    p = data;
    int i;
    for (i=0;i<wc;i++) {
        index_size = strlen(p) + 1 + 2*sizeof(int);
        if (strcmp(word, p) == 0) {
            flag = 1;
        }
        if (flag == 1) {
            offset = ntohl(*(int *)(p + strlen(p) + 1));
            size   = ntohl(*(int *)(p + strlen(p) + 1 + sizeof(int)));
            //printf("offset=%dnsize%dn",offset,size);
            /*gzFile zfile;
            zfile = gzopen("./dic/stardict-langdao-ec-gb-2.4.2/langdao-ec-gb.dict.dz", "rb");
            gzseek(zfile, offset, SEEK_SET);
            buf = (unsigned char *)malloc(*size+1);
            memset(buf, '', size+1);
            gzread(zfile, buf, size);
            printf("%sn", buf);
            */
            close(fd);

            if ((fd = open("./dic/stardict-langdao-ec-gb-2.4.2/langdao-ec-gb.dict", O_RDONLY)) < 0) {
                return NULL;
            }
            lseek(fd, offset, SEEK_SET);
            buf = (unsigned char *)malloc(size+1);
            memset(buf, '', size+1);
            read(fd, buf, size);
            //printf("%sn",buf);
            close(fd);
            return Py_BuildValue("s", buf);
        }
        p += index_size;
    }

    return Py_BuildValue("s","");
}

static struct PyMethodDef lookup_methods[] = {
    {"lookup", lookup, 1, "lookup(file_prefix, file_size, wc, word)"},
    {NULL, NULL}
};

void initlookup()
{
    (void) Py_InitModule("lookup", lookup_methods);
}

使用C语言对Python进行扩展挺方便的,http://gashero.yeax.com/?p=38#id7这里有个不错的文档。
完了俺整理整理也放在google code上去。

上面的代码中dict文件需要是未gzip压缩过的,如果在压缩过的我使用被注释掉的那段代码在seek的时候速度很慢,又没办法用mmap,所以暂时就先只使用未压缩过的。

02-26
2009

PyFetion更新

IN:Python, 编程相关   Tags: ,    Comments:39

详细的更新请到google code 查看。

  1. get_info()函数参数处理who遗失的情况;
  2. 向服务器以HTTP方式提交密码时使用urllib.quote()编码;
  3. 修改send_msg()函数;
  4. 清理代码中直接退出的exit函数;
  5. 重写__tcp_recv()函数,以前这里有可能会丢失数据,比如好友列表过长;
  6. 增加隐身登录功能,login(True)表示隐身登录。

以前还有人提到增加隐身登录,我看了下08 PC版的飞信,只能是先登录,然后再设置隐身模式,这样的话增加设置隐身模式就没必要了。

至于登出飞信更是没必要了。

09.02.23 Update:

  1. 上次的代码get_uri被我改出错了,修正了一下;
  2. 修改了使用手机号直接发送的方式,因为目前可以使用tel: 13888888888的方式发送短信,不用从联系人中一个一个找了;不过以前似乎这种方式不行;
  3. 修正了获取联系人信息的XML数据,可以完整的获取联系人;
02-20
2009

导出抓虾收藏

IN:Python, 编程相关   Tags: ,    Comments:3

整理Python写的小工具,发现这个导出抓虾收藏的工具还比较有用,以前也是一同学让帮写的,也放在google code里面
代码

代码把抓虾收藏中的文章全部导出为html格式的书签,方便导入进delicious等书签。

02-04
2009
Page 3 of 812345...Last »
loading...