python requests 發送中文參數的問題
一句話:python requests發送給中文網站的參數,需要先encode為網站對應的編碼。
之前設計了一個 針對朗珈病理查詢系統的爬蟲。設計時向網站提交的剛好是住院號和病理號這些非中文參數,所以當時沒有遇到中文參數這個坑。現在開始折騰影像系統的爬蟲,就遇到了中文參數的問題。
我先使用一個字典來放post的參數:
post_data = { # post_data內容直接複製F12大法裡面的datan keywords_name: 張三n keywords_brbh: ,n keywords_zyh: ,n keywords_mzh: ,n keywords_blh: ,n keywords_sjks: ,n keywords_rqxz: , # %CA%D5%B5%BD%C8%D5%C6%DAn keywords_bgrq1: ,n keywords_bgrq2: ,n Submit: # %B2%E9%D1%AFn }n
然後使用request.post來請求數據:
response = requests.post(request_url, data=post_data, headers=headers)n
結果發現各種姿勢的中文參數都傳不對:
直接在查詢的網頁裡面輸入中文姓名(如「張三」)並查詢,用Fiddler抓包,可以看到上傳的中文參數是這樣的:keywords_name=%D5%C5%C8%FD
,是某種編碼
在python裡面設置: keywords_name: 張三,
Run之後看到上傳的參數變成 keywords_name=%E5%BC%A0%E4%B8%89
。長得和網站的編碼貌似不一樣。
直接把網站用的編碼 keywords_name: %D5%C5%C8%FD
POST上去呢?也不行,抓包可以看到這個字元串變了:keywords_name=%25D5%25C5%25C8%25FD
。在字元串前面加r 、在py文件加 # coding=utf-8
都不行。
Google第一頁的結果也沒有直接的解決方法。《python使用requests模塊參數編碼的不同處理》這篇比較新的博客文章講了requests編碼處理的幾種方法,然而沒有講到點子上。但是在它和《關於在 python 中使用 requests 框架傳入中文參數問題》的啟發下,終於找到了解決方法。
原來 requests.post會把data參數重新編碼,字元串中的%也會變(加了轉義符也沒用),而它編碼之後也跟網站的編碼對不上,所以才不行。
首先,先獲得網站使用的編碼。有的網站如某影像查詢系統是寫在響應頭裡面 charset=GBK
,有的網站如朗珈病理查詢系統是寫在HTML的META標籤時裡面 charset=gb2312
。找不到還可以用 response.apparent_encoding
來獲取網站編碼。
然後,在data字典的鍵值中指定編碼:
post_data = { # post_data內容直接複製F12大法裡面的datan keywords_name: 張三.encode(GB2312), #charset=gb2312 in response METAn keywords_brbh: ,n keywords_zyh: ,n keywords_mzh: ,n keywords_blh: ,n keywords_sjks: ,n keywords_rqxz: , # %CA%D5%B5%BD%C8%D5%C6%DAn keywords_bgrq1: ,n keywords_bgrq2: ,n Submit: # %B2%E9%D1%AFn }n
使用其他的庫如urllib3也能解決這個問題,但貌似也不方便。
原文發表於:python requests 發送中文參數的問題
推薦閱讀:
※字元編碼的奧秘
※如何深入了解python原理?
※Python中對位元組流/二進位流的操作:struct模塊簡易使用教程
※Python GUI教程(一):在PyQt5中創建第一個GUI圖形用戶界面