重定向(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
可以根据以下方式查看
- <head><meta charset="coding">
知道了编码方式后,使用
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'
可以直接使用
在2015/1/7时,百度百科
URL编码 条目重大错误,还不让修改,还能说什么呢
Json解析
json的格式似乎完全符合python内置类型
将字符串转为Python内置类型dict
json.loads(str)
将dict转为json的字符串
json.dumps(json)
未完待续...