Formular absenden und Datei mit Anfragen hochladen
-
21-12-2019 - |
Frage
Ich habe Schwierigkeiten, ein bestimmtes Formular einzureichen Python-Anfragen.Andere Formulare auf der Website, die ich verwenden möchte, funktionieren einwandfrei und ich kann das Anmeldeformular usw. senden.Es ist nur der Datei-Upload, mit dem ich Probleme habe.Das Senden des Formulars funktioniert anscheinend gut, da ich eine Nachricht von der Website erhalte: "Bitte gehen Sie zurück und wählen Sie mindestens eine Bilddatei zum Hochladen." Die Datei wird jedoch nicht auf der Website veröffentlicht.
Wenn ich mir die Anfrage mit dem Firefox-Plugin Tamperdata anschaue, sieht es nach dem Absenden des leeren Formulars so aus:
-----------------------------201075691119887339851216603987\r
Content-Disposition: form-data; name="userfile[]"; filename=""\r
Content-Type: application/octet-stream\r
\r
\r
-----------------------------201075691119887339851216603987\r
Content-Disposition: form-data; name="userfile[]"; filename=""\r
Content-Type: application/octet-stream\r
\r
\r
-----------------------------201075691119887339851216603987\r
Content-Disposition: form-data; name="userfile[]"; filename=""\r
Content-Type: application/octet-stream\r
\r
\r
-----------------------------201075691119887339851216603987\r
Content-Disposition: form-data; name="userfile[]"; filename=""\r
Content-Type: application/octet-stream\r
\r
\r
-----------------------------201075691119887339851216603987\r
Content-Disposition: form-data; name="userfile[]"; filename=""\r
Content-Type: application/octet-stream\r
\r
\r
-----------------------------201075691119887339851216603987\r
Content-Disposition: form-data; name="upload_to"\r
\r
0\r
-----------------------------201075691119887339851216603987\r
Content-Disposition: form-data; name="upload_type"\r
\r
standard\r
-----------------------------201075691119887339851216603987--\r
(Ich habe alle durch Zeilenumbrüche ersetzt, um die Lesbarkeit zu verbessern.)
Mein Python-Upload-Code sieht so aus:
index = s.get("https://example.com/")
file = {'userfile[]': open('tmp/cover/cover.jpg', 'rb')}
res = s.post(url='https://example.com/upload.php',
data=file,
headers={'Content-Type': 'application/octet-stream'})
Das HTML-Formular sieht so aus:
<form action="upload.php" method="post" id="upload_form" enctype="multipart/form-data">
<p>
<input name="userfile[]" type="file" size="30"> <br>
<input name="userfile[]" type="file" size="30"> <br>
<input name="userfile[]" type="file" size="30"> <br>
<input name="userfile[]" type="file" size="30"> <br>
<input name="userfile[]" type="file" size="30"> <br>
<span id="more_file_inputs"></span>
<br>
<span id="upoptions_hidden">
Uploading Options: <a href="javascript:void(0);" onclick="toggle('upoptions_hidden'); toggle('upoptions_shown');">Show</a>
</span>
<span id="upoptions_shown" style="display: none;">
Uploading Options: <a href="javascript:void(0);" onclick="toggle('upoptions_hidden'); toggle('upoptions_shown');">Hide</a>
<br><br>
Upload to:
<select name="upload_to">
<option value="0">Root Album</option>
</select>
<br><br>
Output Layout: <input type="radio" name="upload_type" value="standard" checked="checked"> <span onclick="toggle_lightbox('index.php?layoutprev=std', 'upload_layout_preview_lightbox');" title="Click to preview" class="help">Standard</span> <input type="radio" name="upload_type" value="normal-boxed"> <span onclick="toggle_lightbox('index.php?layoutprev=bx', 'upload_layout_preview_lightbox');" title="Click to preview" class="help">Boxed</span>
</span>
<br><br>
<input class="button1" type="button" value="Add File" onclick="new_file_input();">
<input class="button1" style="font-weight:bold;" type="button" value="Start Upload" onclick="toggle_lightbox('index.php?act=upload_in_progress', 'progress_bar_lightbox'); $('form[id=upload_form]').submit();">
</p>
</form>
Irgendwelche Gedanken darüber, was hier falsch ist oder wie man das besser debuggen kann?Danke schön!
Bearbeiten:Mir ist gerade aufgefallen, dass ich das nicht wirklich eingereicht habe upload_type
Und upload_to
Felder, aber selbst wenn ich sie so einstelle:
file = {'userfile[]': open('tmp/cover/cover.jpg', 'rb'), 'upload_to': '0', 'upload_type': 'standard'}
es funktioniert immer noch nicht.
Lösung
Benutzen Sie die files
Schlüsselwort, um Ihren Upload durchzuführen, nicht data
.Legen Sie auch nicht den Content-Type-Header fest;Das Formular wird als mehrteilige Formulardaten gepostet und Anfragen sollten für Sie den richtigen Inhaltstyp dafür verwenden:
res = s.post(
url='https://example.com/upload.php',
data={'upload_type': 'standard', 'upload_to': '0'},
files=file)
und fügen Sie die restlichen Formularfelder in eine Zuordnung ein data
.
Wenn Sie mehr als eine Datei unter demselben Namen hochladen möchten, verwenden Sie a Reihenfolge Anzahl der Dateien:
files = {
'userfile[]': [
open('tmp/cover/cover1.jpg', 'rb'),
open('tmp/cover/cover2.jpg', 'rb'),
]
}
res = s.post(
url='https://example.com/upload.php',
data={'upload_type': 'standard', 'upload_to': '0'},
files=files)
Andere Tipps
Ich sehe zwei Probleme mit Ihrem Code:
- Sie legen den Inhaltstyp manuell fest. Nicht.Dafür wird die Bibliothek sorgen.Das ist insb.denn während des mehrteiligen Formulardatenbeitrags lauten die Kopfzeilen wie folgt:
Content-Type: multipart/form-data; boundary=<blah>
. - Den Unterlagen zufolge, sollten Sie a verwenden
files
benanntes Argument für das Hochladen einer Datei, nichtdata
.
Verwenden:
res = s.post(url='https://example.com/upload.php',
data=<dict containing form params>,
files=file)