python發起post請求獲取json數據使用requests方法


  最普通的答案

  我一直就覺得GET和POST沒有什么除了語義之外的區別,自打我開始學習Web編程開始就是這么理解的 。

  可能很多人都已經猜到了答案是:

  1.GET 使用URL或Cookie傳參。而POST將數據放在BODY中。

  2.GET 的 URL 會有長度的限制,則POST的數據則可以非常大。

  3.POST比GET安全,因為數據在地址欄上不可見。

  但是很不幸,這些區別都是錯誤的,更不幸的是,這個答案還在Google搜索的頭版頭條,然而我根本沒想到這些是答案,因為在我看來都是錯的。我來解釋一下。

1.GET 和 POST 與數據如何傳參沒有關系

GET和POST是由HTTP協議定義的。在HTTP協議中,Method和Data(URL, Body, Header)是正交的兩個概念,也就是說,使用哪個Method與應用層的數據如何傳輸是沒有相互關系的。

HTTP沒有要求,如果Method是POST數據就要放在BODY中。也沒有要求,如果Method是GET,數據(參數)就一定要放在URL中而不能放在BODY中。

那么,網上流傳甚廣的這個說法是從何而來的呢?我在HTML標准中,找到了相似的描述。這和網上流傳的說法一致。但是這只是HTML標准對HTTP協議的用法的約定。怎么能當成GET和POST的區別呢?

而且,現代的Web Server都是支持GET中包含BODY這樣的請求。雖然這種請求不可能從瀏覽器發出,但是現在的Web Server又不是只給瀏覽器用,已經完全地超出了HTML服務器的范疇了。

知道這個有什么用?我不想解釋了,有時候就得自己痛一次才記得住。

2. HTTP協議對GET和POST都沒有對長度的限制

HTTP協議明確地指出了,HTTP頭和Body都沒有長度的要求。而對於URL長度上的限制,有兩方面的原因造成:

1.瀏覽器。據說早期的瀏覽器會對URL長度做限制。據說IE對URL長度會限制在2048個字符內(流傳很廣,而且無數同事都表示認同)。但我自己試了一下,我構造了90K的URL通過IE9訪問live.com,是正常的。網上的東西,哪怕是Wikipedia上的,也不能信。

2.服務器。URL長了,對服務器處理也是一種負擔。原本一個會話就沒有多少數據,現在如果有人惡意地構造幾個幾M大小的URL,並不停地訪問你的服務器。服務器的最大並發數顯然會下降。另一種攻擊方式是,把告訴服務器Content-Length是一個很大的數,然后只給服務器發一點兒數據,嘿嘿,服務器你就傻等着去吧。哪怕你有超時設置,這種故意的次次訪問超時也能讓服務器吃不了兜着走。有鑒於此,多數服務器出於安全啦、穩定啦方面的考慮,會給URL長度加限制。但是這個限制是針對所有HTTP請求的,與GET、POST沒有關系。

好了 關於 GET 和 POST 就說這些。

接下來我們爬取某個網站網站的數據。首先我們分析一些網站的結構,發現該網站使用ajax請求post提交方式 獲取數據。

  1 # coding=utf-8
  2 import requests
  3 import json
  4 import time
  5 import re
  6 import datetime
  7 import time
  8 import sys
  9 import math
 10 import shutil
 11 import urlparse
 12 from pyquery import PyQuery as pq
 13 from peewee import *
 14 
 15 sys.setrecursionlimit(100000)
 16 reload(sys)
 17 sys.setdefaultencoding('utf8')
 18 str.decode('UTF-8')
 19 
 20 #定義全局變量
 21 global city_sx
 22 global city_ids
 23 global city_names
 24 global city_id_sx
 25 global city_time
 26 #河南省城市id
 27 #1鄭州 2開封 3洛陽 4安陽 5濮陽 6新鄉 7焦作 8三門峽 9鶴壁 10許昌 11漯河 12南陽 13信陽 14濟源 15商丘 16周口 17駐馬店 18平頂山
 28 city_id_sx = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18]
 29 #數據庫城市id
 30 #410000 鄭州,410200 開封,410300 洛陽,410500 安陽,410900 濮陽,410700 新鄉,410800 焦作,411200 三門峽,410600 鶴壁,411000 許昌,411100 漯河,411300 南陽,411500 信陽,410881 濟源,
 31 #411400 商丘,411600 周口,411700 駐馬店,410400 平頂山
 32 city_ids = [410000, 410200, 410300,410500,410900,410700,410800,411200,410600,411000,411100,411300,411500,410881,411400,411600,411700,410400]
 33 #城市名字
 34 city_names = ['鄭州','開封','洛陽','安陽','濮陽','新鄉','焦作','三門峽','鶴壁','許昌','漯河','南陽','信陽','濟源','商丘','周口','駐馬店','平頂山']
 35 #獲取13位的時間戳
 36 # current_milli_time = lambda: int(round(time.time() * 1000))
 37 # city_time = current_milli_time()
 38 # print city_time
 39 
 40 #鏈接數據庫
 41 database = MySQLDatabase('bxy', **{'host': '$', 'password': '$', 'user': '$', 'use_unicode': True, 'charset': 'utf8', 'port': 3306})
 42 
 43 
 44 class UnknownField(object):
 45     def __init__(self, *_, **__): pass
 46 
 47 
 48 class BaseModel(Model):
 49     class Meta:
 50         database = database
 51 
 52 
 53 class Region(BaseModel):
 54     name = CharField()
 55     parent_id = IntegerField(constraints=[SQL("DEFAULT 0")])
 56     rank = IntegerField(constraints=[SQL("DEFAULT 0")], null=True)
 57 
 58     class Meta:
 59         table_name = 'region'
 60 
 61 
 62 class Scens(BaseModel):
 63     address = CharField(null=True)
 64     baidu_lat = DecimalField(constraints=[SQL("DEFAULT 0.0000000000")], null=True)
 65     baidu_lng = DecimalField(constraints=[SQL("DEFAULT 0.0000000000")], null=True)
 66     business_hours = CharField(null=True)
 67     characteristic_landscape = TextField(null=True)
 68     cid = IntegerField()
 69     cname = CharField()
 70     consumer_hotline = CharField(null=True)
 71     interpreter_description = CharField(null=True)
 72     management_agency = CharField(null=True)
 73     pid = IntegerField()
 74     pname = CharField()
 75     price = CharField(null=True)
 76     price_description = CharField(null=True)
 77     scenic_cover = CharField(null=True)
 78     scenic_introduction = TextField(null=True)
 79     scenic_level = IntegerField(null=True)
 80     scenic_site = CharField(null=True)
 81     scenic_spot_description = CharField(null=True)
 82     scenic_title = CharField(null=True)
 83     scenic_type = CharField(null=True)
 84     sid = AutoField()
 85     sname = CharField()
 86     supporting_facilities = TextField(null=True)
 87     tickets_incentives = TextField(null=True)
 88     tour_route = TextField(null=True)
 89     tour_time = CharField(null=True)
 90     tourist_service_center = TextField(null=True)
 91     traffic_guide = TextField(null=True)
 92     xid = IntegerField(constraints=[SQL("DEFAULT 0")], null=True)
 93     xname = CharField(constraints=[SQL("DEFAULT 'unkown'")], null=True)
 94 
 95     class Meta:
 96         table_name = 'scens'
 97 
 98 #圖片處理
 99 def save_img(url):
100     file_name = url.split('/')[-1]
101 
102     try:
103         r = requests.get(url)
104     except:
105         print('遠程連接錯誤')
106         return -1
107 
108     try:
109         with open(file_name, 'wb') as f:
110             f.write(r.content)
111     except:
112         print('文件保存錯誤')
113         return -1
114 
115 
116 def upload_img(url):
117     import os
118     file_name = url.split('/')[-1]
119 
120     im = Image.open(file_name)
121     w, h = im.size
122     # print('Original image size: %sx%s' % (w, h))
123     if w > 640:
124         im.thumbnail((640, int(math.floor(640.00/w*h))))
125         file_name = 'thumbnail.jpg'
126         im.save(file_name, 'jpeg')
127 
128     # print os.getcwd()
129     # os.chdir('%s/scenic_cover' % os.getcwd())
130     folder = datetime.datetime.now().strftime('%Y%m/')
131     data = {
132         'ticket': 'EA8D6730-321B-4B11-9AA2-A925D6E0E91F',
133         'dir': folder
134     }
135     new_file_name = '%s.%s' % (str(uuid.uuid4()), (file_name.split('.')[-1]).lower())
136     files = {'myfile': (new_file_name, open(file_name, 'rb'), 'application/octet-stream', {})}
137     r = requests.post('127.0.0.1/upload/save_remote', data=data, files=files)
138     if r.text == 'true':
139         return '%s%s' % (folder, new_file_name)
140     else:
141         print(r.text)
142         return -1
143 def qs(url):
144     query = urlparse.urlparse(url).query
145     return dict([(k, urlparse.unquote(v[0])) for k, v in urlparse.parse_qs(query).items()])
146 #獲取城市景區鏈接數據
147 def get_city(city_index=0, pg=0, i=0, times=1):
148     global city_id_sx, city_names
149     #print city_id_sx
150     print('\033[0;31m')
151     print '當前:city_id:%d, city_name:%s, city_index:%d, pg:%d, index:%d, times:%d' % (city_id_sx[city_index], city_names[city_index], city_index, pg, i, times)
152     print('\033[0m')
153     print '---------------------->'
154     url = 'http://www.uhenan.com/Interface/getData.ashx'
155     #請求頭
156     headers = {
157         'User-Agent':'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36',
158         'Referer':'http://www.uhenan.com/ScenicArea/List?t1=0&t2=1&t3=%200',
159         'Host':'www.uhenan.com',
160         'Origin':'http://www.uhenan.com',
161         'Content-Type': 'application/x-www-form-urlencoded',
162         'Cookie':'safedog-flow-item=; __51cke__=; __tins__19387303=%7B%22sid%22%3A%201567134818720%2C%20%22vd%22%3A%202%2C%20%22expires%22%3A%201567137385875%7D; __51laig__=20'
163     }
164     try:
165         #發送post請求
166         payload = 'order=desc&field=Top&page=%d&limit=5&method=ScenicArea&Type1=0&Type2=%d&Type3=0&Switch=true&time=' % (city_id_sx[city_index],pg*5)
167         print payload
168         response = requests.post(url=url, headers=headers, timeout=10,data=payload)
169         response.raise_for_status()
170     except requests.exceptions.ConnectTimeout:
171         print('get_city ConnectTimeout')
172         exit(0)
173     except requests.exceptions.Timeout:
174         print('get_city Timeout')
175         exit(0)
176     except requests.exceptions.ConnectionError:
177         print('get_city ConnectionError')
178         exit(0)
179     except requests.RequestException as e:
180         if requests.status_code == 404:
181             print('-' * 20)
182             print(' 沒有此頁。')
183             print('-' * 20)
184         else:
185             print 'get error:', e
186             if item > 4:
187                 exit(0)
188             else:
189                 tiems.sleep(1)
190                 get_detail(cname, city, id, pg, times+1)
191     else:
192         #print response.content
193         json_obj = json.loads(response.content)
194         if len(json_obj['data']) == 0:
195             print '<--- end: city_id:%d, city_name:%s' % (city_id_sx[city_index], city_names[city_index])
196             if city_index < len(city_id_sx) - 1:
197                 print '進入下一個市 ===>'
198                 get_city(city_index+1, 0, 0, 1)
199             else:
200                 print '<=== 本省結束 ===>'
201                 exit(0)
202         for_i = 0
203         for item in json_obj['data']:
204             if i > for_i:
205                 for_i = for_i + 1
206                 continue
207             #獲取子鏈接
208             #ID        = item['ID']
209             #獲取景區名字
210             Title     = item['Title']
211             #獲取景區電話
212             Phone     = item['Phone']
213             #獲取景區價格
214             Ticket    = item['Ticket']
215             str_first = re.sub('<.*?>',"",Ticket)
216             str_enfin = str_first.replace('/n',"") 
217             #獲取景區介紹
218             Introduction = item['Introduction']
219             str_first = re.sub('<.*?>',"",Introduction)
220             str_enfin_1 = str_first.replace('', '')
221             str_enfin_2 = str_enfin_1.replace(' ', '')
222             #獲取景區地址
223             Address   = item['Address']
224             #獲取百度坐標
225             PointLng  = item['PointLng']
226             PointLat  = item['PointLat']
227             #獲取圖片地址:
228             Logo      = item['Logo']
229             http      = 'http://www.uhenan.com'
230             url       = http + Logo
231             print Title, str_enfin, Phone, Address, str_enfin_2, PointLng, PointLat, url
232             # print city_names[city_index], pg+1, for_i+1, scen_item['ID'], scen_item['Title'],scen_item['Phone'],scen_item['Address'],scen_item['PointLng'],scen_item['PointLat']
233             #get_detail(city_names[city_index], city_ids[city_index], ID, pg, 1)
234             time.sleep(1)
235             for_i = for_i + 1
236         get_city(city_index, pg+1, 0, 1)
237 global city
238 
239 if __name__ == '__main__':
240     city_index = 0
241     page = 0
242     index = 0
243 
244     if len(sys.argv) >= 3:
245         city_index = int(sys.argv[1])
246     if len(sys.argv) >= 4:
247         page = int(sys.argv[2])
248     if len(sys.argv) == 5:
249         index = int(sys.argv[3])
250     get_city(city_index, page, index, 1)

 原文轉載鏈接:https://xushanxiang.com/2019/10/python-%e8%8e%b7%e5%8f%96-post-%e5%92%8c-get-%e6%95%b0%e6%8d%ae.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM