PDA

Просмотр полной версии : Заполнение формы с помощью LWP



Question
14.12.2004, 13:50
Добрый день!

Пытаюсь добавить объявление на доску с помощью LWP. Скрипт вроде работает, данные передаются, но объявление упорно не принимается. Передаю Referer, user_agent, Content_type, все поля формы, в т.ч. и скрытые. Может нужно передавать что-то еще (скрипт могу привести)?

И еще. Как передавать текст сообщения с переводами на новую строку? Пробовал так "строка1%0Aстрока2", но сообщение в таком виде и добавляется (это на другой доске). Какие спецсимволы для этого использовать?

Absurd
14.12.2004, 14:06
Content-Length передаешь?

chur
14.12.2004, 14:56
Content-type должен быть такой: application/x-www-form-urlencoded
Перевод строки как ни странно: %0D%0A :)

Question
14.12.2004, 15:29
Content-Length передаешь?
Нет. Надо попробовать


Content-type должен быть такой: application/x-www-form-urlencoded
Там такая форма: <form action="forma.htm" method="post" name="main" enctype="multipart/form-data">
т.е. Content-type должен быть multipart/form-data


Перевод строки как ни странно: %0D%0A
Пробовал и так. Добавляет "строка1%0D%0Aстрока2"

AiK
16.12.2004, 14:30
Question, ты скорее всего формируешь запрос неправильно...

Question
16.12.2004, 21:29
Запрос я формирую вот так:


use LWP::UserAgent;
use HTTP::Request::Common;
use HTTP::Cookies;
my $ua = LWP::UserAgent->new;

$ua->cookie_jar(HTTP::Cookies->new(file => "lwpcookies.txt", autosave => 1));

my $result = $ua->request( POST 'http://урл_скрипта',
user_agent => 'Mozilla/4.0 (compatible; MSIE 5.0; Windows 98) Opera 6.05',
Referer => 'http://урл_скрипта',
Content_type => 'multipart/form-data',
Content => [ MAX_FILE_SIZE => '1000000',
id => '1',
r => '1',
ads => 'строка1%0Aстрока2',
email => 'qwerty@qwerty.com.ua',
firm => 'yyyefrrey',
phone => '(055) 123-12-33',
person => 'qwetrf',
],
);

Это из "поваренной книги lwp", вроде все правильно

chur
16.12.2004, 22:05
Не пробовал просто написать ads => "строка1\nстрока2"? Скорее всего, что LWP ставит на этот параметр Content-Type: text/plain.

AiK
17.12.2004, 02:34
Вообще говоря запрос выглядит несколько странным.
'multipart/form-data' подразумевает одновременную передачу как значений полей формы, так и двоичного контента, т.е. файла.
Тут же имя файла передаётся через куки (я, кстати, предпочитаю их передавать ручками, через соответствующий заголовок: Cookie => 'file="lwpcookies.txt"; autosave=1'), а самого содержимого файла как-то и нет. Что-то мне подсказывает, что если файл не передаётся, то всё ж Content-type должен быть application/x-www-form-urlencoded.

Рекомендую сделать вот что: натравить скрипт на простейший php скрипт:


<?
phpinfo();
?>


После чего туда же перенаправить форму и сравнить полученные результаты. Сразу увидишь, в чём различия.

Question
18.12.2004, 14:00
Не пробовал просто написать ads => "строка1\nстрока2"? Скорее всего, что LWP ставит на этот параметр Content-Type: text/plain.
Пробовал, тоже так и выводит


После чего туда же перенаправить форму и сравнить полученные результаты.
в смысле, что значит перенаправить форму?

AiK
18.12.2004, 14:17
в смысле, что значит перенаправить форму?
Берёшь страницу с формой. Сохраняешь её на диск. И меняешь у неё action URL на http://blabla.ru/test.php.
Заполняешь форму и жмешь пимпу Submit. На открывшейся странице видишь все значения. Твой скрипт их должен передать ровно в том же виде.

chur
18.12.2004, 14:20
Пробовал, тоже так и выводит

В смысле 'тоже так и выводит'? "\n" в двойных кавычках заменяется на символ перевода строки (0x0A) и как строка '\n' появляться не будет. В худшем случае он будет отображаться как пробел, или вообще никак.

Question
18.12.2004, 15:46
2AiK
Сразу бросаются в глаза такие отличия:
1 при запуске с винта есть _REQUEST["submit"] и _POST["submit"] со значением "отправить"
2 CONTENT_TYPE = multipart/form-data; boundary=----------7XJU5qpnvC2H9PpYG2ryab с винта
и
CONTENT_TYPE = multipart/form-data; boundary=xYzZY из скрипта
3 Также отл HTTP_CONNECTION: "Keep-Alive, TE" и "close"

Очень интересна переменная SERVER_ADDR - получается, только по ней можно отлавливать объявления, добавляемые из левых скриптов?

Question
18.12.2004, 16:08
2chur
да, в двойных кавычках все по-другому - вообще бред какой-то получается: все отправляемые поля воспринимаются как 2 сообщения, часть из них добавляется в первое, часть - во второе. Само сообщение добавляется в виде "строка1", т.е. часть "строка2" вообще исчезает

AiK
18.12.2004, 16:30
1) Это по-моему ни на что влиять не должно. Вряд ли скрипт обрабатывает эту переменную, да и скорее всего не все браузеры её передают.
2) То же вряд ли на что влияет. В RFC 2616 можно уточнить, но по-моему важна только уникальность идентификатора, а длина не важна
3) А это уже интересно. Похоже скрипт передаёт запрос по протоколу HTTP/1.0, а не HTTP/1.1. Возможно тебе не хватает заголовка Host.
4) SERVER_ADDR - это адрес, по которому скрипт запускается, в данном случае test.php. Определять левые запросы можно только по полю referer. Защищаться можно и другими способами, но грамотно эмулированный запрос отловить невозможно.

Question
24.12.2004, 23:51
При запуске с винта HTTP_CONNECTION=
Keep-Alive, TE - в опере
Keep-Alive - в ие
У меня получилось передать "Keep-Alive" таким образом:

my $ua = LWP::UserAgent->new(keep_alive=>'1');
"Keep-Alive, TE" передать не получается
Может как-то влияют эти переменные


"HTTP_ACCEPT" = text/html, image/png, image/jpeg, image/gif, image/x-xbitmap, */*
"HTTP_ACCEPT_CHARSET" = windows-1252;q=1.0, utf-8;q=1.0, utf-16;q=1.0, iso-8859-1;q=0.6, *;q=0.1
"HTTP_ACCEPT_ENCODING" = deflate, gzip, x-gzip, identity, *;q=0
"HTTP_ACCEPT_LANGUAGE" = en
"HTTP_TE" = deflate, gzip, chunked, identity, trailers

а что за "заголовок host"?

AiK
25.12.2004, 04:26
Question, rfc2616 (http://www.google.com/search?q=rfc+2616) даст тебе ответы на все вопросы.

Question
29.12.2004, 21:05
нда.. теперь совпадают все переменные кроме одной:

Connection => 'Keep-Alive, TE',
TE => "deflate, gzip, chunked, identity, trailers",
в результате "HTTP_CONNECTION = Keep-Alive, TE, close", т.е. "Keep-Alive, TE" в чистом виде передать не получается
может дело именно в этом?

AiK
30.12.2004, 00:32
Question, ну не предусматривает стандарт такого значения у заголовка. Вообще для HTTP/1.1 имеет смысл указывать только Connection: close, так как по умолчанию подразумевается Keep-Alive. Могу спорить, что форма этот заголовок никак не обрабатывает.

Question
30.12.2004, 17:36
Вообще для HTTP/1.1 имеет смысл указывать только Connection: close, так как по умолчанию подразумевается Keep-Alive
если я не указываю Connection => 'Keep-Alive, TE', то connection=close

Могу спорить, что форма этот заголовок никак не обрабатывает.

3) А это уже интересно. Похоже скрипт передаёт запрос по протоколу HTTP/1.0, а не HTTP/1.1. Возможно тебе не хватает заголовка Host.
я так понял, что дело именно в этом. А как передать Host?

Библиотека автоматически добавляет поля заголовка "Host" и "Content_length" к HTTP запросу перед отправкой его по сети
Может дать урл этой доски? Запрос от формы там обрабатывает та же страница, на к-рой находится форма(причем формат .htm, хотя наверно это неважно). Может есть какие-то особенности, о к-рых я не подозреваю?

AiK
31.12.2004, 02:55
А как передать Host?
согласно rfc2616 так:
Host: www.host.ru

Может дать урл этой доски
Может. Правда очень сомнительно, что там есть "чего-то особенного" ©

Yuri19
13.02.2005, 09:34
Передаю через LWP все параметры формы - сервер их не обрабатывает должным образом. Притом, запрос написанный в окне браузера работает, через LWP нет. Натравил совй свой скрипт на печать $ENV, сделал так чтобы все переменные заголовка совпадали. То же самое. пишу в браузере http://site.ru/search?p1=xxx&p2=yyy - работает, делаю то же из скрипта- нет. Притом все криво получается только при обращеиии с этому урлу только этот урл, другие урлы при таком же подходе работаю как надо.

Вот вкрадце проблема.Чуствую, что решение не в области переменных http-заголовка. Кто-нибудь нашел решение подобной рпоблемы? Подскажите как?