10
21
2010
6

Python HTTP 请求时对重定向中的 cookie 的处理

首先说明一下,我使用的是 Python3 的 urllib,但 Python2.x 同理(使用 urllib2)。

想用脚本去登录一个网站。和很多网站一样,该网站使用 cookie 来保存会话信息。这个我以前是自己提取 response 中的 Set-Cookie 头来处理的。这次本想如法炮制,却发现没保存需要的 cookie,所以登录失败。

很郁闷地想了半天,最后出去 wireshark 抓包,终于发现原来重要的 cookie 在登录后的应答中,但这个应答是个 302 重定向,所以 urllib 默认的 opener (urllib.request.urlopen)直接就跟从这个重定向了,没有对 cookie 进行任何处理。

我首先想到的是,不要跟从重定向。我看到有个 HTTPRedirectHandler,但文档里没写它怎么用。郁闷……自己找到 request.py 文件看源代码,折腾了好久无果,遂想到 Google (早该想到了。。。)于是找到了 StackOverflow 上。有两个解决办法:要么不跟从重定向,要么弄个 HTTPCookieProcessor 保存 cookie 信息。看我自己的需求,当然选后者了。而且,那个回答问题的人也没有给出如何不让它跟从重定向(所给代码只是在重定向前对 cookie 进行处理而已)。

于是,我再一次地打开了 http.cookiejar 的文档,尝试弄明白这东西到底怎么用。当初折腾 cookie 的时候,没弄明白这个,所以才自己处理的。

看 request.py 里的代码,这个 CookieJar 用起来相当不错:

class HTTPCookieProcessor(BaseHandler):
    def __init__(self, cookiejar=None):
        import http.cookiejar
        if cookiejar is None:
            cookiejar = http.cookiejar.CookieJar()
        self.cookiejar = cookiejar

    def http_request(self, request):
        self.cookiejar.add_cookie_header(request)
        return request

    def http_response(self, request, response):
        self.cookiejar.extract_cookies(response, request)
        return response

    https_request = http_request
    https_response = http_response

不过我需要将 cookie 信息保存到文件。从文档上看到有个 FileCookieJar。我尝试了下,出错了,没有 _really_load 方法,我晕。。。之后才注意到其源代码开头有个ASCII图:

						CookieJar____
                        /     \      \
            FileCookieJar      \      \
             /    |   \         \      \
 MozillaCookieJar | LWPCookieJar \      \
                  |               |      \
                  |   ---MSIEBase |       \
                  |  /      |     |        \
                  | /   MSIEDBCookieJar BSDDBCookieJar
                  |/
               MSIECookieJar

原来具体实现还在子类啊。好吧,我就用 MozillaCookieJar 好了。

用法很简单,初始化时把文件名传给它,载入用 load(),保存用 save()。不过要注意的是,文件不存在时不能载入,touch 个空文件出来也不行的。

另外,那个 StackOverflow 的页面还提到了 mechanize 这个模块,有时间去尝试下 :-)

最后,如果我不要它重定向该怎么做呢?难道非要我去用更底层的 http.client?

Category: python | Tags: python 网络
10
15
2010
2

wget 默认文件名附加URL查询部分的去除

拿wget下文件,它总是把URL的查询部分(?q=test这种)附加到默认的文件名后,让人十分不爽。查了man手册,也Google过,结论是没有办法解决。虽说拿shell写个脚本在下载完之后把这种尾巴也不难,但总觉得应该从根本上解决问题。于是就hack源码了。

要改的地方其实很好找,在url.c的第1556行附近:

/* Append "?query" to the file name. */
  u_query = u->query && *u->query ? u->query : NULL;
  if (u_query)
    {
      append_char (FN_QUERY_SEP, &fnres);
      append_uri_pathel (u_query, u_query + strlen (u_query), true, &fnres);
    }

把这几行注释掉,然后重新编译就可以了。不需要安装,可以直接覆盖掉系统的wget,但不推荐,因为更新后就没了。我是把它放到~/bin下。这个目录在我的$PATH变量的前面,所以会优先使用这里的wget。

Category: Linux | Tags: wget C代码
10
14
2010
2

QQ群邮件:美好生活路上的又一障碍

如果能够不用QQ,生活会变得美好。可现实是,我不仅不得不使用QQ,而且还得使用腾讯烂得要命的群邮件服务。

QQ邮箱又挂掉了

WebQQ不知从什么时候开始不再提示新(群)邮件了。由于我们课件什么的都只知道往群邮件里发,我只好每隔几天去查收一次,不然所谓的“超大附件”会过期的。

说起“超大附件”我觉得好笑。现在都什么年代了,我网易邮箱现在6G的存储空间,附件大小可达50M,其它邮箱附件也至少可以20M。我还以为“超大附件”有几百M呢,原来才超过5M就是“超大”了。为什么腾讯不设置成1.44M的限制呢?

看到群邮箱里有不少课件,一个个手动下吧。很快就下好了,结果双击一个PPT,却是用OpenOffice Write打开的,还是空白页面。。。。我还没弄明白出什么事了,到虚拟机的XP里用MS Office打开,结果是“无法打开xxx所代表的文件类型”(微软的用词一向很怪异,我就不追究了)。再试试那些rar文件,也出错。这才注意到文件的大小不对。

OK,算我网络不行,那重新下吧。结果回邮箱里就遇到上面截图里的情况了。。。

这不是我第一次遇到,也不是第二次。我相信也不会是最后一次

唉,难道这就是劣币驱逐良币

PS: wget rocks!

Category: 未分类 | Tags: QQ 腾讯
10
7
2010
3

grub2不显示自定义菜单项的解决

今天弄gparted的live版,在虚拟机里按照这里的说明配置grub2,却始终不见自己新加的菜单项,只好每次尝试启动gparted时手动输入那一串长长的指令,郁闷啊。。。

Google了半天,用中文只能找到些grub2的配置说明的文章,而且代码十分地不整洁,光看到页面鼠标就不由自主地中键点击标签页标题了。于是换用英文,搜索“grub2 menuentry not display”,也没什么有针对性的结果,于是我点了第一项,是Ubuntu的文档。看了一小会儿后,终于有了重大发现——

  • Do not leave empty spaces at the end of lines

再看看自己复制过来的配置,果然在最后一个}后多了一个空格!

但我还是有点纳闷:为什么行末多了一个空格就不行了呢?也没有错误或警告。。。

Category: Linux | Tags: linux grub
9
30
2010
12

colorpicker: 给 Vim 加一个调色板!

作为一名一直喜欢写网页前端的vimmer,自然会使用Vim来编写CSS了。但是,CSS中经常需要调色。虽然相继有一些工具的出现(见可视化的配置Vim(gVim)配色-colorsel.vim),但一直不太理想。编辑CSS的颜色,不仅需要细致的调色,而且需要方便修改,并且支持从屏幕取色是最好不过了!

既然没有现成的,而自己不管怎么说已经入了GTK的门,就自己写了一个简单的工具。本来有个叫gcolor2的调色/取色工具的,可惜它不支持把取到的颜色输出到标准输出,或者任何其它可被其它程序调用的地方(难道这只是某个大牛闲着没事做时写着玩儿的 :-P)。所以,colorpicker与之类似,只有一个标准的GTK调色板。重要的不同之处在于:它可以和其它程序交互。

还是先放个图吧:

就是这样。从图中可以看到,这个标准的调色板除了支持RGB值,还支持HSV,而后者非常适合对色彩进行微调,不像RGB那样只有机器能够理解。左下角有之前颜色和当前颜色的显示(截图时没注意,都是白色。。。)。之前颜色是可以从命令行设置的,这个很有用(请往下看)。也有取色器,在Linux下是可以取到屏幕上任何一点的颜色的。但根据我使用GIMP的经验,好像在Windows上只能取到本程序的颜色。另外还可以看到,图中显示了“透明度”一项。关注Web前端的童鞋都知道,CSS3支持半透明色彩了,所以,本程序也支持输出rgba(79, 0, 159, 0.51)这样的颜色值。

关于程序自身的介绍就到这儿。下面是在Vim里使用的截图:

我需要输入一个颜色值,于是按了我自己定义的Alt-C键,colorpicker启动了。因为是新颜色,加之之前我没使用过,所以“之前颜色”那里显示的是默认的白色。

颜色已经输入了,但我想换一个颜色,怎么办呢?在普通模式下按cac(change a color)就可以了,“之前颜色”会被置为待修改的颜色,方便进行微调。


PS: 在图中可以看到CSS中的颜色值下方背景被高亮成了相应的颜色。这是使用css.vim实现的。

PS2: 这里演示的是修改CSS文件,但实际上是和文件类型无关的。你可以将它用于任何你想用的文件中。

PS3: colorpicker是独立的GTK程序,所以不一定非要和Vim配合工作啦。Emacs什么的一样可以调用,只要有人写出调用代码。

PS4: 程序在哪里下载呢?请移步我的陈列室。Vim调用部分的代码尚未整理,在我的vimrc中,搜索colorpicker就可以了(共两个函数,截图中可以看到函数名。目前(2010年9月30日)它们处于我的vimrc的前50行内)。


2011年4月9日更新

这里 jiazhoulvke 提供了编译好的 Windows 版程序(以及分离出来的 Vim 配置),当然GTK Runtime 环境还是得装,而且还可能遭遇著名的DLL Hell(如果不幸地出现了,那么请把出问题的 DLL 文件从 GTK 的 bin 目录复制到 colorpicker.exe 所在的目录中)。

2014年11月8日更新:

颜色值的高亮显示可以使用 colorizer 插件了哦~

Category: Vim | Tags: gtk css vim C代码
9
28
2010
2

Vim73之ruby $curbuf.number恒为零问题终于解决了!

上回说到Vim7.3在种种优点背后隐藏着种种bug,今天,其中之一终于被解决了!

Command-T 的作者在 vim_use 上的bug报告贴无人回应之后若干天,又在 vim_dev 上发了贴,今天终于有人回应了,指出configure时加上--disable-largefile选项此bug就消失了。我于是迅速地重新编译了下,果然OK了!

Category: Vim | Tags: vim ruby
9
16
2010
9

Vim的hidden选项真是好东西!

我在编辑一些HTML文件。写得觉得差不多了,浏览器里看过还不满足,竟然想到去W3C验证一下。这一验证,差点出大事了!

因为需要使用程序来处理,所以这些HTML文档全部都是合格的XML文件,所以我给它们加上了<?xml version="1.0" encoding="UTF-8"?>。但W3C却告诉我HTML里不能写这个。好吧,我把它们都删掉:

sed -i '/<\?/d'  *.html

我想的是,凡是有<?的行全部删掉。命令执行完后忽然有点不好的感觉,于是ll一下,结果看到了一堆长度为0的HTML文件!我愣了一下,随即欲哭无泪!虽然这些文件在SVN里,但是自我这次开始编辑后我就没提交过!sed也是危险的命令啊!

我只想到火狐里还保留着改动最多的一个页面,赶紧先把它的源代码复制出来。直接“查看源代码”还不管用,因为本地文件是没有缓存的,查看时火狐会去磁盘上找文件。于是打开Firebug,在<html>元素上点右键,复制HTML,然后手工整理。剩下的文件没办法,只有SVN和Vim的*~备份文件了,555……

好吧,我认命。于是我在Vim里打开另一个文件,想趁着还记得改了些什么赶紧重做一遍,却意外地发现打开的文件显示着我sed之前的内容。来不及多想,我赶紧:w保存了,然后想了下,才恍然大悟——

我现在习惯于一直开着一个GVim实例,而又经常只是挂起或者休眠,几天才shutdown一次,所以经常会有100多个buffer。虽然我通常是把hidden选项关闭的,但有时候为方便切换buffer,会去se hidden一下,然后一直忘记再设置回来。这次,不记得什么时候设置了hidden选项,于是,那些被我关闭的buffer都还在内存里!终于知道了hidden在文件已保存的情况下有什么重要作用了!怀着对Vim的感激,我在buffer找到了所有被sed误删的文本,泪流满面~~


2011年3月17日更新:

现在才知道,sed 原来是支持备份的,只要告诉它备份文件的后缀就行了,像这样-i~

另外,Perl 也支持类似的操作,但用的是PCRE,功能强大许多我也熟悉许多。用法是

perl -pin -e 'print /regex/' #相当于 sed -i '/regex/d'
perl -pi -e 's/regex/replacement/g' #相当于 sed -i 's/regex/replacement/g'

 

Category: Vim | Tags: vim 失误 perl sed
9
9
2010
21

成功实现Linux控制台(纯终端)中文显示与宽屏支持

这里的Linux控制台中文显示,当然不是指安装个zhcon/fbterm/fbiterm之类的东东啦。这些东西在我这里都有些bug。zhcon显示效果不错,还支持输入法,但是滚屏的时候文本几乎不动,根本无法正常使用w3m。fbterm显示的字体很丑,特别是在宽屏下。这个可以调,但我没能调出自己觉得满意的。fbiterm显示要好看点。记得都是有些显示上的问题的。在Ubuntu软件源里还有一个日本人做的jfbterm,在我这里有严重bug——启动Vim后无响应,退出出现段错误,然后无论怎么折腾键盘,就是没任何响应了……

我多想控制台能直接支持中文显示啊!

所以,经过长时间的磨砺后,我终于决定自动给内核打上中文显示的补丁。内核源码在http://www.kernel.org/下载,补丁在这里,我只下了前两个补丁。

这里说一下,打补丁的时候可以直接bzcat xxx|patch -p1,不需要先解压(我终于知道bzcat/zcat这种东西有什么用了 =_=!)。另外,记得参数加-p1哦。我不小心用-p0了,结果N多failed,吓到我了呢。

补丁打好后看看README文件就知道怎么编译了,在Arch的Wiki上有更详细的编译和安装说明。下面是我用过的命令——

mkdir ../build
make O=../build menuconfig
# 注意备份 ../build/.config 文件
make O=../build
sudo make O=../build modules_install
cd ../build
sudo cp -v arch/x86/boot/bzImage /boot/vmlinuz-2.6.35.3-lily
sudo cp -v System.map /boot/System.map-2.6.35.3-lily

#Ubuntu 用,注意有个 - 没了。。。
sudo mkinitramfs -k 2.6.35.3lily -o /boot/kernel26-lily
#Arch 用
#sudo mkinitcpio -k 2.6.35.3-lily -g /boot/kernel26-lily

首先是建立了个输出目录。以后几乎所有的make都要加上O=这个目录。第一个make是配置内核,N多选项,一项项看很费时的,而且似乎是根据系统情况生成的。这里和本文主题息息相关的是要记得选上framebuffer支持,然后选个字体编译进去。我还设置了分辨率的,不知道和后来支持宽屏有没有关系。另外,在这里可以启用启动时的图片。不知道是什么的请移步这里。默认的图片是Tux,当然是可以改的,直接替换drivers/video/logo下相应的图片就可以了,比如我替换的是logo_linux_clut224.ppmppm图片可以使用如下命令生成(via):

pngtopnm linuxlogo.png > linuxlogo.pnm
pnmquant 224 linuxlogo.pnm > linuxlogo224.pnm
pnmtoplainpnm linuxlogo224.pnm > linuxlogo224.ppm

这些弄好后就开始make了,很耗时的,我这里大约用了一个多小时。

这些弄完后就可以重启了(要祈祷的哦 :-))。记得给内核传个vga=791之类的参数,虽然说不传这个也是可以显示汉字的。

幸运的话就这么就OK了,不过还不是宽屏的。我这里进X时会出现“工作在低画质模式”的提示,重启X后正常了,再回到控制台下,发现分辨率莫名地变成宽屏的了~~

后来lsmod看到加载了以前安装了但没有用的nouveau驱动,于是把/etc/X11/xorg.conf也给改了:

Section "Device"
        Identifier      "Configured Video Device"
        Driver  "nouveau"
        # Driver        "nvidia"
        Option  "NoLogo"        "True"
EndSection

Section "Module"
        Load    "drm" # 这个是后来加的
        Load    "glx"
EndSection

这样启用nouveau驱动,不用每次进图形界面时重启X了。控制台表现相当完美,除了不知道为什么登录前的那些文字变成了黄色的。。。而且,在图形界面与控制台界面切换相当迅速,不会先黑一下了。

但是——

但是,不能启动compiz了。compiz的有些窗口管理功能还是相当不错的。我尝试重装安装nvidia的官方驱动,新立得告诉我子进程返回了错误号10。去看了下日志:

*** Unable to determine the target kernel version. ***

也就是说,相应的内核模块无法编译了,不知道应该怎么hack,只好暂时放弃了。555...


2012年10月8日更新:在 ChinaUnix 上的补丁已经失效了。这里有另外的人维护的 cjktty 分支可直接使用。说明

2013年10月25日更新:repo.or.cz 上的 cjktty 不再更新了。新的仓库在 GitHub 上

Category: Linux | Tags: linux 中文支持 编译
9
5
2010
2

mutt 带附件转发

mutt带附件转发还真不容易。设置mime_forward_rest变量根本无效,死活就是不带上附近;设置mime_forward倒是把整个邮件都打包成message/rfc822格式的附件发出去了,但叫人怎么读呢?bounce倒是可以,但是不能修改邮件了,大约连原收件人也被bounce给对方了吧。

Google之后,在这里发现了个好办法:

<Esc>e      resend-message         用这封信件作为新信件的模板

这样就可以既编辑信件,又不漏掉附件了。

另外,如果只需要转发附件, 那篇文章还介绍了一个办法,就是在查看附件界面按f转发。这么intuitive的办法我当初怎么没想到呢。。。

Category: Linux | Tags: mutt mail
9
3
2010
5

Vim7.3: 爱你不容易

Vim7.3b出来后我就急不可耐地体验了把,但因为它的ruby支持中$curbuf.number始终返回零,不仅影响到了Command-T插件,也严重影响了我非常喜欢+常用的LustyExplorer插件——时不时地SEGSEGV一下可不行。

等正式版终于出来后,我又立即下载编译了,结果问题依旧。无奈,我只好自己动手,把LustyExplorer中用到$curbuf.number的地方都换成VIM::evaluate('bufnr("%")')了,但之后还是在调用此插件时经常SEGSEGV,郁闷了,于是换回Vim7.2。

但是Vim7.3真的有些很好的特性啊。此前介绍过的就不重复了,下面说说后来发现的两个我很喜欢的特性。

strwidth()函数

strlen()大家都知道,但它求的是字符串的字节数,而不一定等于字符串的宽度,比如中文就是如此。这会造成无法将内容对齐。于是,用于对齐代码的Align插件在处理CJK字符时(设置let g:Align_xstrlen = 3时)使用了一种很耗时的办法来求字符宽度:将字符串显示在Vim里,然后看它占用了多少虚拟列。

有了Vim7.3的strwidth()等函数就不必这么麻烦了。我去改了相关代码,执行效率提升N倍。

setf补全

setf是设置文件类型的指令。这个我很常用,比如写php文件的HTML部分时为了正确地缩进HTML,我会把文件类型设置成HTML,写PHP部分时还要切回去。写新脚本时由于通常没有文件扩展名,所以Vim无法识别文件类型。这些情况我只好手动:setf xxx了。Vim7.3增加了对此的补全支持,可以少敲点字母了。


所以——

所以为了用上Vim7.3,同时又不放弃LustyExplorer插件,我前不久又开始折腾Vim7.3的源代码,最后连gdb都用上了,在段错误时得到以下backtrace结果:

#0  __memset_sse2 () at ../sysdeps/i386/i686/multiarch/memset-sse2.S:160
#1  0x00d1d6ac in Perl_sv_upgrade () from /usr/lib/libperl.so.5.10
#2  0x00d1ea6a in Perl_sv_magicext () from /usr/lib/libperl.so.5.10
#3  0x00d1fc11 in Perl_sv_magic () from /usr/lib/libperl.so.5.10
#4  0x00d21882 in Perl_sv_setiv () from /usr/lib/libperl.so.5.10
#5  0x08203691 in perl_buf_free (bp=0x847b890) at if_perl.xs:638
#6  0x080742e3 in free_buffer (buf=0x847b890) at buffer.c:613
#7  0x08073fec in close_buffer (win=0x0, buf=0x847b890, action=4)
    at buffer.c:468
#8  0x08074de8 in do_buffer (action=4, start=0, dir=1, count=0, forceit=1)
    at buffer.c:1136
#9  0x0807465e in do_bufdel (command=4, arg=0x84b8aa1 "", addr_count=0, 
    start_bnr=12, end_bnr=1, forceit=1) at buffer.c:834
#10 0x080cbb2c in ex_bunload (eap=0xbfff9f8c) at ex_docmd.c:4939
#11 0x080c817d in do_one_cmd (cmdlinep=0xbfffa140, sourcing=1, 
    cstack=0xbfffa148, fgetline=0, cookie=0x0) at ex_docmd.c:2656
#12 0x080c5a56 in do_cmdline (cmdline=0x837c2d0 "bwipeout!", getline=0, 
    cookie=0x0, flags=11) at ex_docmd.c:1122
#13 0x080c5110 in do_cmdline_cmd (cmd=0x837c2d0 "bwipeout!") at ex_docmd.c:728
#14 0x0820cf98 in vim_command (self=3084803600, str=3084486540) at if_ruby.c:731
#15 0x010619a3 in ?? () from /usr/lib/libruby1.8.so.1.8
---Type  to continue, or q  to quit---

接着我很快发现了问题——明明是个ruby写的插件,最上面怎么调用到Perl了呢?遂关闭+perl特性重新编译,几天已经过去了,Vim7.3依旧运行良好,没有再出现以下烦人的提示了:

Vim: 拦截到致命信号(deadly signal) SEGV
Vim: 结束。
zsh: segmentation fault  vim

现在我一直在关注 ftp://ftp.vim.org/pub/vim/patches/7.3/,期待着这个问题从根本上解决……

Category: Vim | Tags: vim ruby

部分静态文件存储由又拍云存储提供。 | Theme: Aeros 2.0 by TheBuckmaker.com