Python论坛  - 讨论区

标题:[python-chinese] urllib2 不能添加 HTTP header "Connection:Keep-Alive" 的问题

2007年02月01日 星期四 15:03

Leira Hua lhua在altigen.com.cn
星期四 二月 1 15:03:11 HKT 2007

需要一个脚本,用来下载处理这个文件  
http://training.cusa.com:81/IVRService/fiapi?WSDL

原先脚本中为了方便先调用wget下载,已经完成了。但是因为是给windows下的朋友用 
的,所以,还是用urllib或者urllib2比较方便。

首先尝试用  
urllib.urlopen("http://training.cusa.com:81/IVRService/fiapi?WSDL") 得到了 
HTTP Status 500。后来ethereal抓包对比发现,是因为这个站点要求HTTP header  
"Connection:Keep-Alive" 才能下载。


然后尝试用 urllib2
urllib2.urlopen("http://training.cusa.com:81/IVRService/fiapi?WSDL")
得到的HTTP request包中是"Connection:close",下载失败,HTTP Status 500。


request =  
urllib2.Request("http://training.cusa.com:81/IVRService/fiapi?WSDL")
opener = urllib2.build_opener()
request.add_header('Connection', 'Keep-Alive')
opener.open(request)
得到的HTTP request包中是"Connection:close",下载失败,HTTP Status 500。


request.headers.pop('Connection')
opener.addheaders = [('Connection', 'Keep-Alive')]
opener.open(request)
得到的HTTP request包中是"Connection:close",下载失败,HTTP Status 500。

看来是怎么加都是"Connection:close",于是看urllib2.py,发现在  
AbstractHTTPHandler.do_open()函数中:

         # We want to make an HTTP/1.1 request, but the addinfourl
         # class isn't prepared to deal with a persistent connection.
         # It will try to read all remaining data from the socket,
         # which will block while the server waits for the next request.
         # So make sure the connection gets closed after the (only)
         # request.
         headers["Connection"] = "close"
         try:
             h.request(req.get_method(), req.get_selector(), req.data,  
headers)
             r = h.getresponse()
         except socket.error, err: # XXX what error?
             raise URLError(err)

看来是这个代码已经被固化在了这个函数中,如果要做,除非是特化自己的Handler, 
然后重写do_open()。看他的注释,似乎是因为addinfourl这个类的原因,只能使用 
"Connection:close",具体如何,没有进一步深究。只是,这么设计,从最底层hard  
code了"Connection:close",使得urllib2的使用者没有便利的方式改变这种逻辑,甚 
至得到违背直观的结果,直到看源代码才能明白,我觉得可能不见得是一个好的做 
法。不知道urllib2的设计者是怎么想的。


后来回头看了urllib源代码,就没有这个hard code的代码,而且FancyURLopener看来 
也堪用,只是lib manual上没有细讲,于是还是转用urllib:
opener = urllib.FancyURLopener()
opener.addheader('Connection', 'Keep-Alive')
remortefile =  
opener.open("http://training.cusa.com:81/IVRService/fiapi?WSDL")
就搞定了。


-- 
Leira Hua
http://my.opera.com/Leira


[导入自Mailman归档:http://www.zeuux.org/pipermail/zeuux-python]

2007年02月01日 星期四 15:13

limodou limodou在gmail.com
星期四 二月 1 15:13:24 HKT 2007

On 2/1/07, Leira Hua <lhua在altigen.com.cn> wrote:
> 需要一个脚本,用来下载处理这个文件
> http://training.cusa.com:81/IVRService/fiapi?WSDL
>
> 原先脚本中为了方便先调用wget下载,已经完成了。但是因为是给windows下的朋友用
> 的,所以,还是用urllib或者urllib2比较方便。
>
[snip]

有意思.

-- 
I like python!
UliPad <>: http://wiki.woodpecker.org.cn/moin/UliPad
My Blog: http://www.donews.net/limodou

[导入自Mailman归档:http://www.zeuux.org/pipermail/zeuux-python]

2007年02月01日 星期四 15:20

yi huang yi.codeplayer在gmail.com
星期四 二月 1 15:20:52 HKT 2007

On 2/1/07, Leira Hua <lhua at altigen.com.cn> wrote:
>
> 需要一个脚本,用来下载处理这个文件
> http://training.cusa.com:81/IVRService/fiapi?WSDL
>
> 原先脚本中为了方便先调用wget下载,已经完成了。但是因为是给windows下的朋友用
> 的,所以,还是用urllib或者urllib2比较方便。
>
> 首先尝试用
> urllib.urlopen("http://training.cusa.com:81/IVRService/fiapi?WSDL") 得到了
> HTTP Status 500。后来ethereal抓包对比发现,是因为这个站点要求HTTP header
> "Connection:Keep-Alive" 才能下载。
>
>
> 然后尝试用 urllib2
> urllib2.urlopen("http://training.cusa.com:81/IVRService/fiapi?WSDL")
> 得到的HTTP request包中是"Connection:close",下载失败,HTTP Status 500。
>
>
> request =
> urllib2.Request("http://training.cusa.com:81/IVRService/fiapi?WSDL")
> opener = urllib2.build_opener()
> request.add_header('Connection', 'Keep-Alive')
> opener.open(request)
> 得到的HTTP request包中是"Connection:close",下载失败,HTTP Status 500。
>
>
> request.headers.pop('Connection')
> opener.addheaders = [('Connection', 'Keep-Alive')]
> opener.open(request)
> 得到的HTTP request包中是"Connection:close",下载失败,HTTP Status 500。
>
> 看来是怎么加都是"Connection:close",于是看urllib2.py,发现在
> AbstractHTTPHandler.do_open()函数中:
>
>         # We want to make an HTTP/1.1 request, but the addinfourl
>         # class isn't prepared to deal with a persistent connection.
>         # It will try to read all remaining data from the socket,
>         # which will block while the server waits for the next request.
>         # So make sure the connection gets closed after the (only)
>         # request.
>         headers["Connection"] = "close"
>         try:
>             h.request(req.get_method(), req.get_selector(), req.data,
> headers)
>             r = h.getresponse()
>         except socket.error, err: # XXX what error?
>             raise URLError(err)
>
> 看来是这个代码已经被固化在了这个函数中,如果要做,除非是特化自己的Handler,
> 然后重写do_open()。看他的注释,似乎是因为addinfourl这个类的原因,只能使用
> "Connection:close",具体如何,没有进一步深究。只是,这么设计,从最底层hard
> code了"Connection:close",使得urllib2的使用者没有便利的方式改变这种逻辑,甚
> 至得到违背直观的结果,直到看源代码才能明白,我觉得可能不见得是一个好的做
> 法。不知道urllib2的设计者是怎么想的。
>
>
> 后来回头看了urllib源代码,就没有这个hard code的代码,而且FancyURLopener看来
> 也堪用,只是lib manual上没有细讲,于是还是转用urllib:
> opener = urllib.FancyURLopener()
> opener.addheader('Connection', 'Keep-Alive')
> remortefile =
> opener.open("http://training.cusa.com:81/IVRService/fiapi?WSDL")
> 就搞定了。
>
>
> --
> Leira Hua
> http://my.opera.com/Leira
>
> _______________________________________________
> python-chinese
> Post: send python-chinese at lists.python.cn
> Subscribe: send subscribe to python-chinese-request at lists.python.cn
> Unsubscribe: send unsubscribe to  python-chinese-request at lists.python.cn
> Detail Info: http://python.cn/mailman/listinfo/python-chinese


keep-alive 是 http persistent connection 了,urllib 没有实现这个特性,所以不允许 keep-alive 。
试试 httplib2 <http://bitworking.org/projects/httplib2/> 。

-- 
http://codeplayer.blogspot.com/
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://python.cn/pipermail/python-chinese/attachments/20070201/a23b2345/attachment-0001.html 

[导入自Mailman归档:http://www.zeuux.org/pipermail/zeuux-python]

2007年02月01日 星期四 17:29

kuafoo lovegroups在gmail.com
星期四 二月 1 17:29:06 HKT 2007

ûÓÐÓöµ½¹ýÕâÖÖÇé¿ö   Ö±½ÓÓÃsocketÈçºÎÄØ

2007/2/1, yi huang <yi.codeplayer在gmail.com>:
>
> On 2/1/07, Leira Hua <lhua在altigen.com.cn> wrote:
> >
> > ÐèÒªÒ»¸ö½Å±¾£¬ÓÃÀ´ÏÂÔØ´¦ÀíÕâ¸öÎļþ
> > http://training.cusa.com:81/IVRService/fiapi?WSDL
> >
> > Ô­ÏȽű¾ÖÐΪÁË·½±ãÏȵ÷ÓÃwgetÏÂÔØ£¬ÒѾ­Íê³ÉÁË¡£µ«ÊÇÒòΪÊǸøwindowsϵÄÅóÓÑÓÃ
> > µÄ£¬ËùÒÔ£¬»¹ÊÇÓÃurllib»òÕßurllib2±È½Ï·½±ã¡£
> >
> > Ê×Ïȳ¢ÊÔÓÃ
> > urllib.urlopen("http://training.cusa.com:81/IVRService/fiapi?WSDL ") µÃµ½ÁË
> > HTTP Status 500¡£ºóÀ´ethereal×¥°ü¶Ô±È·¢ÏÖ£¬ÊÇÒòΪÕâ¸öÕ¾µãÒªÇóHTTP header
> > "Connection:Keep-Alive" ²ÅÄÜÏÂÔØ¡£
> >
> >
> > È»ºó³¢ÊÔÓà urllib2
> > urllib2.urlopen(" http://training.cusa.com:81/IVRService/fiapi?WSDL")
> > µÃµ½µÄHTTP request°üÖÐÊÇ"Connection:close"£¬ÏÂÔØʧ°Ü£¬HTTP Status 500¡£
> >
> >
> > request =
> > urllib2.Request(" http://training.cusa.com:81/IVRService/fiapi?WSDL")
> > opener = urllib2.build_opener()
> > request.add_header('Connection', 'Keep-Alive')
> > opener.open(request)
> > µÃµ½µÄHTTP request°üÖÐÊÇ"Connection:close"£¬ÏÂÔØʧ°Ü£¬HTTP Status 500¡£
> >
> >
> > request.headers.pop('Connection')
> > opener.addheaders = [('Connection', 'Keep-Alive')]
> > opener.open(request)
> > µÃµ½µÄHTTP request°üÖÐÊÇ"Connection:close"£¬ÏÂÔØʧ°Ü£¬HTTP Status 500¡£
> >
> > ¿´À´ÊÇÔõô¼Ó¶¼ÊÇ"Connection:close"£¬ÓÚÊÇ¿´urllib2.py£¬·¢ÏÖÔÚ
> > AbstractHTTPHandler.do_open()º¯ÊýÖУº
> >
> >         # We want to make an HTTP/1.1 request, but the addinfourl
> >         # class isn't prepared to deal with a persistent connection.
> >         # It will try to read all remaining data from the socket,
> >         # which will block while the server waits for the next request.
> >         # So make sure the connection gets closed after the (only)
> >         # request.
> >         headers["Connection"] = "close"
> >         try:
> >             h.request(req.get_method(), req.get_selector(), req.data,
> > headers)
> >             r = h.getresponse()
> >         except socket.error , err: # XXX what error?
> >             raise URLError(err)
> >
> > ¿´À´ÊÇÕâ¸ö´úÂëÒѾ­±»¹Ì»¯ÔÚÁËÕâ¸öº¯ÊýÖУ¬Èç¹ûÒª×ö£¬³ý·ÇÊÇÌØ»¯×Ô¼ºµÄHandler£¬
> > È»ºóÖØдdo_open()¡£¿´ËûµÄ×¢ÊÍ£¬ËƺõÊÇÒòΪaddinfourlÕâ¸öÀàµÄÔ­Òò£¬Ö»ÄÜʹÓÃ
> > "Connection:close"£¬¾ßÌåÈçºÎ£¬Ã»ÓнøÒ»²½É¡£Ö»ÊÇ£¬ÕâôÉè¼Æ£¬´Ó×îµ×²ãhard
> > codeÁË"Connection:close"£¬Ê¹µÃurllib2µÄʹÓÃÕßûÓбãÀûµÄ·½Ê½¸Ä±äÕâÖÖÂß¼­£¬Éõ
> > ÖÁµÃµ½Î¥±³Ö±¹ÛµÄ½á¹û£¬Ö±µ½¿´Ô´´úÂë²ÅÄÜÃ÷°×£¬ÎÒ¾õµÃ¿ÉÄܲ»¼ûµÃÊÇÒ»¸öºÃµÄ×ö
> > ·¨¡£²»ÖªµÀurllib2µÄÉè¼ÆÕßÊÇÔõôÏëµÄ¡£
> >
> >
> > ºóÀ´»ØÍ·¿´ÁËurllibÔ´´úÂ룬¾ÍûÓÐÕâ¸öhard codeµÄ´úÂ룬¶øÇÒFancyURLopener¿´À´
> > Ò²¿°Óã¬Ö»ÊÇlib manualÉÏûÓÐϸ½²£¬ÓÚÊÇ»¹ÊÇתÓÃurllib£º
> > opener = urllib.FancyURLopener()
> > opener.addheader('Connection', 'Keep-Alive')
> > remortefile =
> > opener.open("http://training.cusa.com:81/IVRService/fiapi?WSDL ")
> > ¾Í¸ã¶¨ÁË¡£
> >
> >
> > --
> > Leira Hua
> > http://my.opera.com/Leira
> >
> > _______________________________________________
> > python-chinese
> > Post: send python-chinese在lists.python.cn
> > Subscribe: send subscribe to python-chinese-request在lists.python.cn
> > Unsubscribe: send unsubscribe to  python-chinese-request在lists.python.cn
> > Detail Info: http://python.cn/mailman/listinfo/python-chinese
>
>
> keep-alive ÊÇ http persistent connection ÁË£¬urllib ûÓÐʵÏÖÕâ¸öÌØÐÔ£¬ËùÒÔ²»ÔÊÐí keep-alive
> ¡£
> ÊÔÊÔ httplib2 <http://bitworking.org/projects/httplib2/> ¡£
>
> --
> http://codeplayer.blogspot.com/
>
> _______________________________________________
> python-chinese
> Post: send python-chinese在lists.python.cn
> Subscribe: send subscribe to python-chinese-request在lists.python.cn
> Unsubscribe: send unsubscribe to  python-chinese-request在lists.python.cn
> Detail Info: http://python.cn/mailman/listinfo/python-chinese
>
-------------- 下一部分 --------------
Ò»¸öHTML¸½¼þ±»ÒƳý...
URL: http://python.cn/pipermail/python-chinese/attachments/20070201/289242ca/attachment.htm 

[导入自Mailman归档:http://www.zeuux.org/pipermail/zeuux-python]

如下红色区域有误,请重新填写。

    你的回复:

    请 登录 后回复。还没有在Zeuux哲思注册吗?现在 注册 !

    Zeuux © 2025

    京ICP备05028076号