Как установить файлы cookie в методе Http Get с помощью Java

Я хочу выполнить ручной GET с файлами cookie, чтобы загрузить и проанализировать веб-страницу. Мне нужно извлечь токен безопасности, чтобы опубликовать сообщение на форуме. Я завершил вход, прочитал ответ и извлек файлы cookie (3 пары (имя, значение)). Затем я написал строку, содержащую файлы cookie, следующим образом:

CookieString="name1=value1; name2=value2; name3=value3"

Затем я делаю следующее

HttpURLConnection connection
connection = (HttpURLConnection)(new URL(Link).openConnection());
connection.setRequestMethod("GET");
connection.setRequestProperty("Connection", "Keep-Alive");
connection.setRequestProperty("Cookie", CookieString );
connection.connect();

Затем я прочитал страницу, но она показывает, что я не зарегистрирован на форуме. Что я делаю не так?

edit: я знаю, что должен извлечь токен безопасности, если хочу опубликовать сообщение. Я думал, что для того, чтобы извлечь его, мне нужно ПОЛУЧИТЬ эту конкретную страницу. Но для того, чтобы токен безопасности был скрытым полем, я должен быть в сети, поэтому мне нужны файлы cookie. Но когда я ПОЛУЧАЮ страницу и устанавливаю файлы cookie, как указано выше, я получаю страницу как гость, это показывает, что я не в сети, а значение токена безопасности - гость, что мне не полезно. Я проверю ссылку, которую вы мне дали, и, надеюсь, найду решение.


person fysob    schedule 14.07.2010    source источник


Ответы (3)


Чтобы быть уверенным, вы должны собирать файлы cookie из заголовков ответа Set-Cookie. Чтобы отправить их обратно в последующих запросах, вы должны установить их один за другим, используя URLConnection#addRequestProperty().

В принципе:

// ...

// Grab Set-Cookie headers:
List<String> cookies = connection.getHeaderFields().get("Set-Cookie");

// ...

// Send them back in subsequent requests:
for (String cookie : cookies) {
    connection.addRequestProperty("Cookie", cookie.split(";", 2)[0]);
}

// ...

split(";", 2) предназначен для того, чтобы избавиться от атрибутов файлов cookie, которые не имеют значения для серверной стороны, таких как expires, path и т. д.

Для более удобного HTTP-клиента я бы посоветовал взглянуть на Клиент Apache HttpComponents. Он может более прозрачно обрабатывать все файлы cookie.

Смотрите также:


Обновление: судя по комментариям, это не проблема с файлами cookie. Неправильный токен запроса означает, что сервер имеет встроенную защиту от CSRF/ботов (для предотвращения таких людей, как вы). Вам нужно извлечь токен как скрытое поле ввода с запрашиваемой страницы с формой и повторно отправить его как параметр запроса. Jsoup может быть полезен для извлечения всех (скрытых) полей ввода. Не забудьте также передать пару «имя-значение» кнопки, которую вы хотите нажать программно. Также смотрите вышеупомянутую ссылку для получения дополнительных советов.

В будущем вы действительно должны быть более четкими в отношении точной ошибки, которую вы извлекаете, а не угадывать что-то наугад. Скопируйте точное сообщение об ошибке и так далее.

person BalusC    schedule 14.07.2010
comment
Это то, что я делаю, и это не работает. Я прочитал файлы cookie из заголовков Set-Cookie ответа. Раньше я устанавливал их все вместе с помощью setRequestProperty. Я пробовал один за другим с addRequestProperty, но результат был таким же. Я не могу найти, что я делаю неправильно. Я бы предпочел избегать использования сторонней библиотеки, если это было возможно. - person fysob; 14.07.2010
comment
Тогда проблема кроется в другом. Что такое URL? Что говорит инструмент отслеживания HTTP, такой как Fiddler? - person BalusC; 14.07.2010
comment
URL-адрес представляет собой страницу ответа на сообщение на форуме vbulletin. Странно то, что когда я использую куки по той же ссылке с методом POST для отправки ответа, ответ представляет собой страницу, которая говорит, что у меня нет действительного токена безопасности, но видит, что я в сети, поэтому куки работают. Когда я пытаюсь ПОЛУЧИТЬ ту же страницу с теми же файлами cookie, чтобы извлечь токен безопасности, он просит меня войти в систему. Я установлю fiddler, посмотрю, как он работает, и свяжусь с вами. Если у вас есть идеи, пожалуйста, скажите мне. - person fysob; 14.07.2010
comment
FWIW, для людей, работающих на Android, я недавно пытался прикрепить несколько файлов cookie к UrlConnection и обнаружил, что addRequestProperty() на самом деле не добавляет несколько заголовков с одним и тем же именем. Это наблюдение может быть неверным, но единственный способ, которым я мог заставить сервер распознавать мои несколько файлов cookie, — это объединить их в один String, разделив их ;. Затем установите этот единственный String с addRequestProperty()/setRequestProperty() в заголовок Cookie, как показано выше. Кажется, я нахожу противоречивую информацию о том, что на самом деле делают addRequest... и setRequest.... - person Tony Chan; 04.02.2014
comment
Попробовал это, и я считаю, что cookie.split(";", 1)[0] должно быть cookie.split(";", 2)[0] (параметр limit указывает количество возвращаемых частей, где последняя часть автоматически занимает оставшуюся часть строки). - person Chiara Coetzee; 17.06.2015
comment
вызов addRequestProperty(Cookie, .....) в цикле приведет к недопустимому заголовку файла cookie! см. здесь: stackoverflow .com/questions/55512910/ - person riskop; 04.04.2019

Предполагая, что значения cookie не жестко закодированы, а получены из предыдущего запроса, вероятно, проще всего использовать класс CookieHandler.

CookieHandler.setDefault(new CookieManager());

Затем ваш HttpURLConnection автоматически сохранит все полученные файлы cookie и отправит их обратно со следующим запросом на тот же хост.

person finnw    schedule 14.07.2010

// Grab Set-Cookie headers:
List<String> cookies = connection.getHeaderFields().get("Set-Cookie");

// ...

// Send them back in subsequent requests:
for (String cookie : cookies) {
    connection.addRequestProperty("Cookie", cookie.split(";", 1)[0]);
}

Приведенный выше код будет работать для отправки нескольких файлов cookie, просто используйте setRequestProperty вместо addRequestProperty. Рабочий код:

// Grab Set-Cookie headers:
List<String> cookies = connection.getHeaderFields().get("Set-Cookie");

// ...

// Send them back in subsequent requests:
for (String cookie : cookies) {
    connection.setRequestProperty("Cookie", cookie.split(";", 1)[0]);
}
person Rohit Haval    schedule 14.03.2013