可可熊的窝

更新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

8 Comments for 更新PyFetion && getsong

Leave a Comment

loading...