Отправьте форму и загрузите файл с запросами

StackOverflow https://stackoverflow.com//questions/20019600

  •  21-12-2019
  •  | 
  •  

Вопрос

Я борюсь с отправкой определенной формы с помощью запросы python.Другие формы на сайте, которые я хочу использовать, работают нормально, и я могу отправить форму входа в систему и т.д.У меня просто проблемы с загрузкой файла.По-видимому, отправка формы работает нормально, потому что я получаю сообщение с сайта со словами "Пожалуйста, вернитесь и выберите хотя бы один файл изображения для загрузки". но файл не размещен на сайте.

Если я посмотрю на запрос с помощью плагина Firefox Tamperdata, он будет выглядеть следующим образом после отправки пустой формы:

-----------------------------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

(Я заменил все на разрывы строк, чтобы сделать его немного более читабельным)

Мой код загрузки на python выглядит следующим образом:

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'})

HTML-форма выглядит следующим образом:

<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>

Есть какие-нибудь мысли о том, что здесь не так, или о лучшем способе отладки этого?Спасибо!

Редактировать:Я только что понял, что на самом деле я не представлял upload_type и upload_to поля, но даже если я установлю их как:

file = {'userfile[]': open('tmp/cover/cover.jpg', 'rb'), 'upload_to': '0', 'upload_type': 'standard'}

это все еще не работает.

Это было полезно?

Решение

Используйте files ключевое слово для вашей загрузки, а не data.Также не устанавливайте заголовок content-type;форма публикуется в виде данных формы, состоящей из нескольких частей, и в запросах должен использоваться правильный для вас тип контента:

res = s.post(
    url='https://example.com/upload.php',
    data={'upload_type': 'standard', 'upload_to': '0'},
    files=file)

и поместите остальные поля формы в сопоставление в data.

Если вы хотите загрузить более одного файла под одним и тем же именем, используйте последовательность файлов:

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)

Другие советы

Я вижу две проблемы с вашим кодом:

  • Тип содержимого устанавливается вручную. Не надо.Библиотека позаботится об этом.Это экстрасенс.потому что во время публикации данных многокомпонентной формы заголовки имеют вид: Content-Type: multipart/form-data; boundary=<blah>.
  • Согласно документам, вы должны использовать files именованный аргумент для загрузки файла, а не data.

Использование:

res = s.post(url='https://example.com/upload.php',
            data=<dict containing form params>,
            files=file)
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top