Python-HttpClient开发常见问题与解决

重定向(302 Found)

根据返回的头部(headers)中的Location的值,确定要跳转的地址
由于可能存在多次跳转,比如打开天猫商品的详细信息,会跳转两次。
如果返回值为302,就一直连接重定向的地址

import urllib.request
import http.client
conn=http.client.HTTPConnection("detail.tmall.com")
conn.request("POST","/item.htm?spm=a220o.1000855.w5003-9379371941.2.MMSfwC&&id=41211262327&scene=taobao_shop")
r1=conn.getresponse()
print(r1.status,r1.reason)
while r1.status==302:
    jump=r1.headers["Location"];
    left=jump.find("//",0)
    right=jump.find("/",left+2)
    connResult=http.client.HTTPConnection(jump[left+2:right])
    connResult.request("GET",jump[right])
    r1=connResult.getresponse()
    print(r1.status,r1.reason)
f=open("result.txt","w")
f.write(str(r1.read()))
f.close()


编码问题

上面的倒数第二行代码,str(r1.read())返回的字符串有乱码,因为收到的数据是gbk编码,在显示之前,需要将其解码转化为unicode,才能正常显示
网页常见编码有utf-8和gbk
可以根据以下方式查看
知道了编码方式后,使用
bytes.decode(encoding="utf-8", errors="strict")
转化为字符串,再将其保存或显示

花样做死之乱加header(Accept-Encoding)

为了假装我是一个真人(显然没人在意),把chrome里的常用请求头加入。
headers["Connection"]="keep-alive"
headers["Cache-Control"]="max-age=0"
headers["Accept-Language"]="zh-CN,zh;q=0.8"
headers["Accept-Encoding"]="gzip, deflate, sdch"
headers["Accept"]="text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8"

结果报错
UnicodeDecodeError: 'gbk' codec can't decode byte 0x8b in position 1: illegal multibyte sequence

查看网页编码,确实是gbk.然后我尝试把
gbk改成utf-8,错
utf-8改成gb2312,错
gb2312改成gb18030,错
折腾一晚上才发现
headers["Accept-Encoding"]="gzip, deflate, sdch"
出了问题,只要去掉,就可以正常解码
经过我的多次尝试,deflate,sdch均可以正常解码,而gzip不行并且服务器倾向于发gzip

URL里的中文转换

如果url含有中文,会出现如下错误
UnicodeEncodeError: 'ascii' codec can't encode character '\u82f9' in position 0: ordinal not in range(128)
url会以ascii编码的形式发送,中文需先手动修改
修改规则
将中文的unicode对应的值转为十六进制,并且每8位前加%号,如"苹果“转为十六进制
b'\xe8\x8b\xb9\xe6\x9e\x9c'
变成url就为
'%E8%8B%B9%E6%9E%9C'
可以直接使用
urllib.parse.quote("苹果")
在2015/1/7时,百度百科 URL编码 条目重大错误,还不让修改,还能说什么呢

Json解析

json的格式似乎完全符合python内置类型
将字符串转为Python内置类型dict
json.loads(str)
将dict转为json的字符串
json.dumps(json)

未完待续...


你可能感兴趣的:(Python)