Ruby open-uri и cookies
Я хотел бы сохранить файлы cookie с одного вызова open-uri и передать их на следующий. Кажется, я не могу найти правильные документы для этого. Я был бы признателен, если бы вы могли сказать мне правильный способ сделать это.
ПРИМЕЧАНИЯ: w3.org не является фактическим URL, но он короче; притворяйтесь, что кулинарные вещи здесь.
h1 = open("http://www.w3.org/")
h2 = open("http://www.w3.org/People/Berners-Lee/", "Cookie" => h1.FixThisSpot)
Обновление после 2 дней. Хотя это не было риторическим вопросом, я гарантирую, что это возможно.
Обновление после перекачки: см. (ответ), это возможно. Принял меня хорошо, но он работает.
Ответы
Ответ 1
Я думал, что кто-то просто узнает, но я думаю, что это не принято делать с open-uri
.
Здесь уродливая версия, которая не проверяет конфиденциальность, срок действия, правильный домен и правильный путь:
h1 = open("http://www.w3.org/")
h2 = open("http://www.w3.org/People/Berners-Lee/",
"Cookie" => h1.meta['set-cookie'].split('; ',2)[0])
Да, это работает. Нет, это не красиво, не полностью соответствует рекомендациям и не обрабатывает несколько файлов cookie (как есть).
Очевидно, что HTTP - это очень прямой протокол, а open-uri
позволяет вам в большинстве своем. Я предполагаю, что мне действительно нужно было знать, как получить файл cookie из запроса h1
, чтобы он мог быть передан в запрос h2
(эта часть, которую я уже знал и показывал). Удивительно, что многие люди в основном чувствовали себя как ответ, говоря мне, чтобы я не использовал open-uri
, и только один из них показал, как получить набор файлов cookie в одном запросе, переданный следующему запросу.
Ответ 2
Вам нужно добавить заголовок "Cookie".
Я не уверен, что open-uri может это сделать или нет, но это можно сделать с помощью Net:: HTTP.
# Create a new connection object.
conn = Net::HTTP.new(site, port)
# Get the response when we login, to set the cookie.
# body is the encoded arguments to log in.
resp, data = conn.post(login_path, body, {})
cookie = resp.response['set-cookie']
# Headers need to be in a hash.
headers = { "Cookie" => cookie }
# On a get, we don't need a body.
resp, data = conn.get(path, headers)
Ответ 3
Спасибо, Мэтью Шинкель, ваш ответ был действительно полезен. Использование Net:: HTTP я был успешным
# Create a new connection object.
site = "google.com"
port = 80
conn = Net::HTTP.new(site, port)
# Get the response when we login, to set the cookie.
# body is the encoded arguments to log in.
resp, data = conn.post(login_path, body, {})
cookie = resp.response['set-cookie']
# Headers need to be in a hash.
headers = { "Cookie" => cookie }
# On a get, we don't need a body.
resp, data = conn.get(path, headers)
puts resp.body
Ответ 4
В зависимости от того, что вы пытаетесь выполнить, проверьте webrat. Я знаю, что он обычно используется для тестирования, но он также может поражать сайты в реальном времени, и он делает много вещей, которые ваш веб-браузер сделает для вас, например, куки файлы cookie между запросами и последующие переадресации.
Ответ 5
вам нужно будет свернуть свою собственную поддержку файлов cookie, проанализировав заголовки метаданных при чтении и добавлении заголовка файла cookie при отправке запроса, если вы используете open-uri. Рассмотрите возможность использования httpclient http://raa.ruby-lang.org/project/httpclient/ или что-то вроде механизации вместо http://mechanize.rubyforge.org/, поскольку они поддерживают встроенную поддержку файлов cookie.
Ответ 6
Здесь есть реализация jQ файла cookie RFC 2109 и RFC 2965, для которого требуется стандартная совместимая обработка файлов cookie.
https://github.com/dwaite/cookiejar