2013-08-09 3 views
3

Это мой первый вопрос, поэтому, пожалуйста, будь хорошим, если я, в любом случае, делаю это неправильно.Как скачать файл с сайта

Я использую модуль запросов в python 3.3 для автоматизации загрузки файлов с нескольких сайтов, но this one, в частности, создает проблемы при попытке получить файл csv. У меня работоспособный уровень компетенции в python, но я не знаком с html и javascript в отношении взаимодействия с веб-сайтом.

Вот соответствующий код.

import requests 
import datetime 

now = datetime.datetime.now().strftime("%Y%m%d") 

folder = 'some path' 

url = 'https://gats.pjm-eis.com/gats2/PublicReports/RenewableGeneratorsRegisteredInGATS/'#ExportTo' 
payload = {'exportType' : 'CSV', 
      'tabNumber' : ''} 
doc = requests.post(url, data=payload, stream=True) 

output = open(folder+now+'_GATSRegistered.csv','wb') 
output.write(doc.content) 
output.close() 

У меня нет ошибок, но создаваемый документ основан на странице с ошибкой. Я успешно сделал это для сайта, где url указал прямо на файл ('http://www.place.com/path/file.xlsx), поэтому я знаю, что делать с файлом после его получения. Но это просто потребовало запроса «получить».

Итак, мои вопросы:

  • Что такое правильный запрос к сообщению?
  • Является ли сообщение даже правильной вещи?
  • Это особый случай или что-то, что я должен знать, как обращаться в целом?
  • Что-нибудь еще я должен делать по-другому?
+3

Нужно было бы взглянуть на ключевое слово Python 'to' для открытия файлов. Он автоматически закрывает их. – iCodez

+1

Сообщение для отправки данных на сервер, get для его получения (хотя он также может отправлять данные, но не надежно). – rlms

+0

@ user2387370 Когда я использую get, я просто получаю исходную страницу, как будто никакой полезной нагрузки не было. Я думал, что мне нужно отправить некоторые данные, чтобы сервер знал, что я нажал кнопку CSV, но вы говорите, что это можно сделать с помощью get? – ess

ответ

1

Я просмотрел страницу в Chrome и открыл консоль разработчиков с открытой вкладкой в ​​сети. Там вы можете увидеть, что нажатие кнопки «CSV» отправляет запрос POST с большим количеством данных формы.

exportType:CSV 
tabNumber: 
CSV_CH:1 
PRN_CH:0 
GridView$DXFREditorcol0: 
GridView$DXFREditorcol1: 
GridView$DXFREditorcol2: 
GridView$DXFREditorcol3: 
GridView$DXFREditorcol4: 
GridView$DXFREditorcol5: 
GridView$DXFREditorcol6: 
GridView$DXFREditorcol7: 
GridView$DXFREditorcol8: 
GridView$DXFREditorcol9: 
GridView$DXFREditorcol10: 
GridView$DXFREditorcol11: 
GridView$DXFREditorcol12: 
GridView$DXFREditorcol13: 
GridView$DXFREditorcol14: 
GridView$DXFREditorcol15: 
GridView$DXFREditorcol16: 
GridView$DXFREditorcol17: 
GridView$DXFREditorcol18: 
GridView$DXFREditorcol19: 
GridView$DXFREditorcol20: 
GridView$DXFREditorcol21: 
GridView$DXFREditorcol22: 
GridView$DXFREditorcol23: 
GridView$DXFREditorcol24: 
GridView$DXFREditorcol25: 
GridView$DXFREditorcol26: 
GridView_custwindowWS:0:0:-1:-10000:-10000:0:1px:-10000:1:0:0:0 
GridView_DXHFPWS:0:0:-1:-10000:-10000:0:180px:100px:1:0:0:0 
GridView_DXPagerBottom_PSPSI:2 
GridView$DXSelInput: 
GridView$DXKVInput:[] 
GridView$CallbackState:BwMHAQIFU3RhdGUGEAEHGwcAAgEHAQIBBwICAQcDAgEHBAIBBwUCAQcGAgEHBwIBBwgCAQcJAgEHCgIBBwsCAQcMAgEHDQIBBw4CAQcPAgEHEAIBBxECAQcSAgEHEwIBBxQCAQcVAgEHFgIBBxcCAQcYAgEHGQIBBxoCAQcABxsHAAcABwEHAAcCBwAHAwcABwQHAAcFBwAHBgcABwcHAAcIBwAHCQcABwoHAAcLBwAHDAcABw0HAAcOBwAHDwcABxAHAAcRBwAHEgcABxMHAAcUBwAHFQcABxYHAAcXBwAHGAcABxkHAAcaBwAHAAcAAgAFAAAAgAkCCUVudGl0eUtleQkCAAIAAwcEAgAHAAIBBTaVAAAHAAIBBwAHAAIQRmlsdGVyRXhwcmVzc2lvbgcCAAIIUGFnZVNpemUDBzI= 
GridView$DXSyncInput: 
GridView_DXFilterRowMenuCI: 
DXScript:1_142,1_80,1_135,1_91,14_0,1_90,1_113,14_23,14_10,1_98,1_105,1_77,1_128,1_126,1_124,1_133,1_119,1_127,1_104,1_101,1_84,1_109,1_92,14_1,1_94,1_97,1_95,1_96,1_106,14_4,1_100,1_117,1_103,14_12,14_13,1_102,1_129,1_107,1_137,1_114,14_16,10_2,10_1,10_3,10_4,14_3 
DXMVCEditorsValues:{"GridView_DXFREditorcol0":null,"GridView_DXFREditorcol1":null,"GridView_DXFREditorcol2":null,"GridView_DXFREditorcol3":null,"GridView_DXFREditorcol4":null,"GridView_DXFREditorcol5":null,"GridView_DXFREditorcol6":null,"GridView_DXFREditorcol7":null,"GridView_DXFREditorcol8":null,"GridView_DXFREditorcol9":null,"GridView_DXFREditorcol10":null,"GridView_DXFREditorcol11":null,"GridView_DXFREditorcol12":null,"GridView_DXFREditorcol13":null,"GridView_DXFREditorcol14":null,"GridView_DXFREditorcol15":null,"GridView_DXFREditorcol16":null,"GridView_DXFREditorcol17":null,"GridView_DXFREditorcol18":null,"GridView_DXFREditorcol19":null,"GridView_DXFREditorcol20":null,"GridView_DXFREditorcol21":null,"GridView_DXFREditorcol22":null,"GridView_DXFREditorcol23":null,"GridView_DXFREditorcol24":null,"GridView_DXFREditorcol25":null,"GridView_DXFREditorcol26":null} 

Вы можете увидеть, что из перечисленного абсолютно необходимо для отправки на сервер. Я сомневаюсь, что все они требуются (но я ошибался много :)).

При этом, используя stream=True, вы должны использовать iter_content. Таким образом, ваш код будет выглядеть так:

payload = { 
# Form contents 
} 
r = requests.post(url, data=payload, stream=True) 
with open(filename, 'wb') as output: 
    for chunk in r.iter_content(): 
     output.write(chunk) 

For-loop гарантирует, что по мере его поступления он будет записан в ваш файл. Когда он застопорился, вам не придется беспокоиться о том, что он висит на вас.

+0

Отлично; это очень полезно. Я не думаю, что все данные формы будут абсолютно необходимы, но для доказательства концепции я сначала их пытаюсь. Как мне перевести представление консоли Chrome в python/request? Я не знаю, что должно быть массивом, списком, dict, строкой и т. Д. – ess

+0

Похоже, что на сайте используется уникальный идентификатор для предотвращения сквозного мошенничества, который имеет побочный эффект предотвращения пост-взаимодействия на этом уровне (Я думаю). Тем не менее, этот ответ правильный. – ess

Смежные вопросы