【问题】
Python中,前面已经实现了模拟登陆百度,并且获得返回的cookie等信息。
接下来去打开某个网页,然后解析内容。
结果打开网页的时候,出错,对应代码为:
req = urllib2.request(loginBaiduUrl, postData); req.add_header('user-agent', gconst['useragentie9']); req.add_header('cache-control', 'no-cache'); req.add_header('accept', '*/*'); #req.add_header('accept-encoding', 'gzip, deflate'); req.add_header('connection', 'keep-alive'); resp = urllib2.urlopen(req);
但是同样的代码,在前面去模拟登陆网站,提交http的请求,打开网页,都是OK的,都没出现错误。
为何在这里,却出现错误了。
【解决过程】
1.怀疑是由于前面模拟登陆后,获得cookie,把登陆信息的cookie,冲突掉了,然后访问网页,结果出错了。
所以去测试了一下,但是很奇怪的,为何前面的网页访问是正常的。
2. 想要搞懂到底urllib2,出了具体哪个错误,所以添加了对应的代码:
try: req = urllib2.request(loginBaiduUrl, postData); req.add_header('user-agent', gconst['useragentie9']); req.add_header('cache-control', 'no-cache'); req.add_header('accept', '*/*'); #req.add_header('accept-encoding', 'gzip, deflate'); req.add_header('connection', 'keep-alive'); resp = urllib2.urlopen(req); except urllib2.URLError,reason : logging.warning(" URLError when open %s, reason=%s", url, reason) except urllib2.HTTPError,code : logging.warning(" HTTPError when open %s, code=%s", url, code) except : logging.warning(" Unknown error when open %s", url)
但是运行结果始终都是Unknown error,既不是URLError,也不是HTTPError,觉得很是奇怪。
3.后来无意间,试了试:
resp = urllib2.urlopen(url);
好像是可以运行的,但是由于好像访问网页,没有用到cookie,所以返回页面内容页不对,所以还是没有解决问题。
4.最后,无意间发现,好像别人介绍关于Python中关于urllib2的使用:urllib2模块学习笔记
中urllib2.Request的Request的首字母是大写的R,而不是小写的r,不是urllib2.request,而是urllib2.Request,
然后就是试了试,改为urllib2.Request,结果果然此一行,是可以正常运行了。
所以,至此,得出的结论是,Python中,对于库函数的大小写是敏感的,所以库函数写错了,那当然会出错。
5.但是,对于剩下的那些行:
req.add_header('user-agent', gconst['useragentie9']); req.add_header('cache-control', 'no-cache'); req.add_header('accept', '*/*'); #req.add_header('accept-encoding', 'gzip, deflate'); req.add_header('connection', 'keep-alive'); resp = urllib2.urlopen(req);
还是无法正常运行,第一行:
req.add_header(‘user-agent’, gconst[‘useragentie9’]);
就会出错,后来发现,好像其他地方可以正常运行的代码是:
req.add_header(‘User-Agent’, gConst[‘userAgentIE9’]);
而此处的是:
req.add_header(‘user-agent’, gconst[‘useragentie9’]);
很明显,是被全部改为小写了,然后,才注意到,原来,上面那么多行的代码,
从开始的urllib2.request,到后面的req.add_header(‘connection’, ‘keep-alive’);,都是小写。
6.接着就是找原因,为何此处都是变成小写了。
后来才想起来,编辑Python代码期间,由于是用的Notepad++,某次,不小心,按了Ctrl+U,
其会把所选内容转换为小写:
所以,才导致此处这段代码,全部变成小写的。
7.然后才想起来,刚刚误以为的,以为对于:
req.add_header(‘user-agent’, gconst[‘useragentie9’]);
中的user-agent,必须要写成User-Agent呢,实际上不是,
实际上此行错误,是由于gconst[‘useragentie9’]中的useragentie9,不存在此key,所以才导致引用变量gconst[‘useragentie9’]而出错的。
而对于http的header,user-agent和User-Agent,都是可以的,因为其是大小写不敏感的。
而对应的引用变量gconst[‘useragentie9’]出错,按理来说应该是提示KeyError的,但是由于此处没有添加:
except KeyError: logging.warning(" KeyError when open %s", url)
之类的代码,导致最后的Exception会跑到Unknown error的部分,提示Unknown error。
【总结】
1.Notepad++,虽然很好用,但是却也会发生这样不小心把代码都变成小写的事情,很是无语。算是自己使用不当。
2.对于Python,尤其常遇到的就是KeyError,而且是不小心写错大小写字母而导致的,此种问题,如果不是错误提示中包含KeyError,那么调试bug,找原因的过程,则会极其痛苦,往往找不到具体的出错原因和位置。
所以,以后需要对于Python中的变量书写,要很小心,尽量不要犯这种低级错误了。
但是也由此看出,Python这种解释性语言的一个弊端,那就是变量名写错了,都只能在运行期间才能发现,
因为其没有编译过程,没法像其他编译性语言,在编译期间就发现这类变量名写错的事情。
转载请注明:在路上 » 【教训记录】Python中用urllib2.request和add_header,然后去打开网页的时候出现未知错误