记录新人Python入门学习过程踩过的坑

       最近几天有点空暇时间,一直想了解下Python,对于一个有其它语言经验的工程师来说,学习一门新语言最快的方式是直接写一个简易流程的Demo,于是选择了Python的常规领域--爬虫。
我选择了一个后台平台,目的是通过Python模拟登录,再爬取数据商品清单,最后模拟Post请求实现自动下单功能。
        所谓要想熟悉一门开发语言,就准备好踩各种各样的坑,踩着踩着坑顺了,你会突然发现你已经入门了,尤其对于Python这样的语言。具体学习过程暂且不说,我将我遇到的坑记录下来,以便后续有朋友在以后开发过程遇到同类问题可以参考,节省时间。


一坑目:数据题交方式Form Data和Request Payload是由区别的
        按照网上的资料,要爬取一个需要登录后页面的数据,首先需要模拟登录,登录成功后保存登录Cookie,再用request的get方法获取页面数据。好的,似乎很简单,当使用网页调试工具查看的时候,没有Form Data,只有Request Payload,一开始没在意两者区别,试了几下没有达到预期结果,才查看资料,原来Request Payload的方式是页面通过Ajax调用的,一般采用json数据格式发送。于是定义登录数据login_data的json格式数据,再在post的时候转为字符串形式实现模拟登录,session.post("http://www.*************", data = json.dumps(login_data),headers=myheader)成功。

        为什么不直接data=login_data,因为login_data定义的类型是dict,不能直接post。


二坑目:Request获取到的页面没有指定的数据
        登录完成后,返回的response.text没有看到想要爬的数据,只是返回一个固定的Html,没有任何数据,这个坑对于小白的我来说百思不得其姐,一度以为是模拟登录没有成功,甚至是header不匹配,body内就是没有数据。后来发现网页右键查看源代码也是这样,于是找到了查问题的关键词,“网页右键查看源代码内容空”,知道通过js的方式获取数据由于异步加载的问题,不会在html标签中显示数据。但是当以为解决了问题的我,通过开发调试工具查看所有的js,将全部js一个一个拷贝到浏览器去浏览,依旧没有查找到页面中的数据。无意中看到JS左边那个XHR标签,点击进去突然发现都是.do的文件,原来数据全部在这里。原来网站开发人员直接采用WebAPI接口的方式获取数据。真想打死平台开发人员,接口获取数据返回Json数据,都不需要通过标签解析了。

三坑目:因中文出现编码编译出错以及中文乱码
        既然实现了模拟登录和登录后数据获取,接下来就是模拟下单指令,让程序自己去下一个单。通过开发者调试工具,发现只要做一个Json数据Post到指定URL就可以了,So Easy!然后我还是Too Yuang Too Simple,接下来一个一个预料外的问题接踵而来,让我脑瓜子不停的嗡嗡的。


意外一、'ascii' codec can't decode byte 0xe3 in position 42......
        我拼装的json数据如下:

        通过度娘,很快知道了原因,Python采用的是ASCII 编码方式,而ASCII 编码只支持拉丁语系字符,不支持中文(花了1-2个小时重新认识了ASC、Unicode 、GBK等编码方式和网络传输编码、转义等原理),而我在json数据组合中包含了中文字符,PythonIDE这个老外在编译时代码文件时,不认识中文才报的错误。
        既然知道了原因,就能解决问题,于是自做聪明的我在中文字符前加了字母u,让中文字符转为unicode编码格式,然而问题依旧。继续度娘,资料说
        session.post("http://www.*******.do", data = json.dumps(buy_data),headers = myheader)这个 json.dumps方法需要加ensure_ascii=False这个参数,否则将以ascii码进行编码转换,于是我改为data = json.dumps(buy_data,ensure_ascii=False)重新进行Post,提交成功!当我长舒一口气以为可以手工时发现后台页面显示的中文全部显示乱码。。。。。


意外二、Json中文数据Post到服务器显示中文乱码
        在通过度娘多次搜索了“Python Request Post Json 中文乱码”这样的关键词后,始终得不到解决,因为我陷入了一个不深入研究问题本质,只通过百度搜索类似问题就解决问题的困境中,比如尝试在python代码头部加了编码申明“# _*_ coding:utf-8 _*_”,尝试在中文字符串之前加u,都无法解决问题。同时通过浏览器调试工具,确定服务器端Request的header中Content-Type中charset = utf-8,但时结果就是乱码,曾一度陷入绝望。
        我想看看request到底给我post去处了什么东西,于是安装抓包工具Fiddle发现,程序提交的数据在Fiddle中显示中文部分也是乱码,那就确定post的data有编码问题,我想我理真想越来越近了,于是锁定罪魁祸首json.dumps。但是此时我知道所以然,不知道之所以然,于是重新了解Python的编码机制,通过chardet包查看字符串编码,
        >>>import chardet
        >>>print chardet.detect(json.dumps(buy_data,ensure_ascii=False))
        输出:
        {'confidence': 0.99, 'language': 'Chinese', 'encoding': 'GB2312'}
        终于!知道乱码的原因了,Post过去的数据编码时GB2312,服务器解析的Utf-8,于是强制修改编码
        data = json.dumps(buy_data,ensure_ascii=False).decode("GB2312").encode('utf-8')

为什么decode("GB2312").encode('utf-8'),因为Python采用Unicode作为中间编码,GB2312需要先转为中间编码Unicode再转为目标utf-8。
成功!

        心得:整个demo断断续续花费的不少时间,一度在数据和编码问题卡了好多时间,通过不停的卡壳,不挺的查找原因,分析问题,最终解决问题的过程是收货巨大的,通过这么一个简短的demo让我了解了Http协议的基本内容和工作方式,编码解码的来龙去脉,这些都是在历年项目开发中用到但又不会去深究的问题,恰恰这些对看似简单问题的深究才是程序员进阶的关键!

猜你喜欢

转载自www.cnblogs.com/minfengstar/p/10398515.html