Как скачать файл, возвращенный «косвенно» (??) из HTML-формы представления?(python, urllib, urllib2 и т. д.) - PullRequest
2 голосов
/ 30 сентября 2011

РЕДАКТИРОВАТЬ: Проблема решена. В конечном итоге это оказалось вопросом http: вместо URL https: в URL (просто глупая ошибка с моей стороны). Но это был хороший чистый пример кода от cetver, который помог мне изолировать проблему. Спасибо всем, кто предложил предложения.

Помещение этого URL в Firefox вызывает соответствующий диалог загрузки и сохранения как:

https://www.virwox.com/orders.php?download_open=Download&format_open=.xls

Приведенная выше ссылка аналогична отправке формы с кнопкой «скачать» на странице https://www.virwox.com/orders.php.

Вот соответствующий HTML-код для формы, которая генерирует вышеуказанный URL:

<form action='orders.php' method='get'><fieldset><legend>Open Orders (2):</legend>
  <input type='submit' value='Download' name='download_open' /> 
  <select name='format_open'>
    <option value='.xls'>.xls</option>
    <option value='.csv'>.csv</option>
    <option value='.xml'>.xml</option></select>
</form>

Но когда я попробую следующий код на Python (который я вроде бы не сработает) ...

# get orders list
openOrders_url = virwoxTopLevel_url+"/orders.php"
openOrders_params = urlencode( { "download_open":"Download", "format_open":".xml" } )
openOrders_request = urllib2.Request(openOrders_url,openOrders_params,headers)
openOrders_response = virwox_opener.open(openOrders_request)
openOrders_xml = openOrders_response.read()
print(openOrders_xml)

... openOrders_xml заканчивается только тем, что является исходной страницей (https://www.virwox.com/orders.php).

Как Firefox узнает, что файл также должен быть загружен, и как мне обнаружить и загрузить этот файл в Python?

Обратите внимание, что это не проблема безопасности / входа в систему, поскольку я даже не смог бы получить страницу orders.php, если бы у меня были проблемы с аутентификацией.

РЕДАКТИРОВАТЬ: мне интересно, связано ли это с перенаправлением (я использую основной обработчик перенаправления) или, возможно, мне следует использовать что-то liek urllib.fileretrieve ().

РЕДАКТИРОВАТЬ: вот код для полной программы, на всякий случай имеет отношение ...

import urllib
import urllib2
import cookielib
import pprint

from urllib import urlencode

username=###############
password=###############

virwoxTopLevel_url = "http://www.virwox.com/"

overview_url = "https://www.virwox.com/index.php"


# Header
user_agent = 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)'
headers = { 'User-Agent' : user_agent }

# Handlers...
# cookie handler...
cookie_handler= urllib2.HTTPCookieProcessor( cookielib.CookieJar() )
# redirect handler...
redirect_handler= urllib2.HTTPRedirectHandler()

# create "opener" (OpenerDirector instance)
virwox_opener = urllib2.build_opener(redirect_handler,cookie_handler)

# login
login_url = "https://www.virwox.com/index.php"
values = { 'uname' : username, 'password' : password }
login_data = urllib.urlencode(values)
login_request = urllib2.Request(login_url,login_data,headers)
login_response = virwox_opener.open(login_request)

overview_html = login_response.read();

virwox_json_url = "http://api.virwox.com/api/json.php"
getTest = urllib.urlencode( { "method":"getMarketDepth", "symbols[0]":"EUR/SLL","symbols[1]":"USD/SLL","buyDepth":1,"sellDepth":1,"id":1 } )
get_response = urllib2.urlopen(virwox_json_url,getTest)
#print get_response.read()

# get orders list
openOrders_url = virwoxTopLevel_url+"/orders.php"
openOrders_params = urlencode( { "download_open":"Download", "format_open":".xml" } )
openOrders_request = urllib2.Request(openOrders_url,openOrders_params,headers)
openOrders_response = virwox_opener.open(openOrders_request)
openOrders_xml = openOrders_response.read()

# the following prints the html of the /orders.php page not the desired download data:
print "******************************************"
print(openOrders_xml)

print "******************************************"
print openOrders_response.info()
print openOrders_response.geturl()
print "******************************************"
# the following prints nothing, i assume because without the cookie handler, fails to authenticate
#  (note that authentication is by the php program, not html authentication, so no "authentication hangler" above
print urllib2.urlopen("https://www.virwox.com/orders.php?download_open=Download&format_open=.xml").read()

Ответы [ 3 ]

1 голос
/ 30 сентября 2011

Похоже, что на ваш вопрос уже дан ответ, но вы можете взглянуть на пакет Requests .По сути, это хорошая оболочка для стандартных инструментов lib.Следующее (вероятно) делает то, что вы хотите.

import requests

r = requests.get('http://www.virwox.com/orders.php', 
    allow_redirects=True,
    auth=('user', 'pass'), 
    data={'download_open': 'Download', 'format_open': '.xls'})

print r.content
1 голос
/ 30 сентября 2011

КОД НИЖЕ ПРОВЕРЕН

что-то вроде:

import urllib, urllib2,

HOST = 'https://www.virwox.com'
FORMS = {
    'login': {
        'action': HOST + '/index.php',
        'data': urllib.urlencode( {
            'uname':'username', 
            'password':'******'
        } )
    },
    'orders': {
        'action': HOST + '/orders.php',
        'data': urllib.urlencode( {
            'download_open':'Download', 
            'format_open':'.xml'
        } )
    }
}

opener = urllib2.build_opener( urllib2.HTTPCookieProcessor() )
try:
    req = urllib2.Request( url = FORMS['login']['action'], data = FORMS['login']['data'] )
    opener.open( req ) #save login cookie
    print 'Login: OK'
except Exception, e:
    print 'Login: Fail'
    print e   
try:
    req = urllib2.Request( url = FORMS['orders']['action'], data = FORMS['orders']['data'] )
    print 'Orders Page: OK'
except Exception, e:
    print 'Orders Page: Fail'
    print e
try:
    xml = opener.open( req ).read()
    print xml
except Exception, e:
    print 'Obtain XML: Fail'
    print e
0 голосов
/ 30 сентября 2011

Вам может понадобиться urllib2.HTTPPasswordMgr как этот (не проверено, так как у меня нет вашего uname / pw):

import urllib
import urllib2

uri = "http://www.virwox.com/"
url = uri + "orders.php"
uname = "USERNAME"
password = "PASSWORD"
post = urllib.urlencode({"download_open":"Download", "format_open":".xls"})
pwMgr = urllib2.HTTPPasswordMgr()
pwMgr.add_password(realm=None, uri=uri, user=uname, passwd=password)
urllib2.install_opener(urllib2.build_opener(urllib2.HTTPDigestAuthHandler(pwMgr)))
req = urllib2.Request(url, post)
s = urllib2.urlopen(req)
cookie = s.headers['Set-Cookie']
s.close()

req.add_header('Cookie', cookie)

s = urllib2.urlopen(req)
source = s.read()
s.close()

Затем вы можете:

print source

чтобы узнать, содержит ли он нужные вам XML-данные.

...