Подтвердить что ты не робот

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 дней. Хотя это не было риторическим вопросом, я гарантирую, что это возможно. Обновление после перекачки: см. (ответ), это возможно. Принял меня хорошо, но он работает.

4b9b3361

Ответ 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