web-dev-qa-db-fra.com

Comment enregistrer des cookies de demandes (python) dans un fichier?

Comment utiliser la bibliothèque requests (en python) après une requête

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import requests
bot = requests.session()
bot.get('http://google.com')

conserver tous les cookies dans un fichier, puis les restaurer à partir d’un fichier.

32
agrynchuk

Il n'y a pas de moyen immédiat de le faire, mais ce n'est pas difficile à faire.

Vous pouvez obtenir un objet CookieJar à partir de la session sous la forme session.cookies, vous pouvez utiliser pickle pour le stocker dans un fichier.

Un exemple complet:

import requests, pickle
session = requests.session()
# Make some calls
with open('somefile', 'wb') as f:
    pickle.dump(session.cookies, f)

Le chargement est alors:

session = requests.session()  # or an existing session

with open('somefile', 'rb') as f:
    session.cookies.update(pickle.load(f))

La bibliothèque de requêtes utilise la sous-classe requests.cookies.RequestsCookieJar() , qui prend explicitement en charge le pickling et une API de type dict, et vous pouvez utiliser la méthode RequestsCookieJar.update() pour mettre à jour un cookie de session existant avec ceux chargés à partir d’un fichier pickle.

48
madjar

Après un appel tel que r = requests.get(), r.cookies renverra une RequestsCookieJar que vous pouvez directement pickle , i.e.

import pickle
def save_cookies(requests_cookiejar, filename):
    with open(filename, 'wb') as f:
        pickle.dump(requests_cookiejar, f)

def load_cookies(filename):
    with open(filename, 'rb') as f:
        return pickle.load(f)

#save cookies
r = requests.get(url)
save_cookies(r.cookies, filename)

#load cookies and do a request
requests.get(url, cookies=load_cookies(filename))

Si vous souhaitez enregistrer vos cookies dans un format lisible par l'homme, vous devez effectuer quelques opérations pour extraire la RequestsCookieJar en un LWPCookieJar .

import cookielib
def save_cookies_lwp(cookiejar, filename):
    lwp_cookiejar = cookielib.LWPCookieJar()
    for c in cookiejar:
        args = dict(vars(c).items())
        args['rest'] = args['_rest']
        del args['_rest']
        c = cookielib.Cookie(**args)
        lwp_cookiejar.set_cookie(c)
    lwp_cookiejar.save(filename, ignore_discard=True)

def load_cookies_from_lwp(filename):
    lwp_cookiejar = cookielib.LWPCookieJar()
    lwp_cookiejar.load(filename, ignore_discard=True)
    return lwp_cookiejar

#save human-readable
r = requests.get(url)
save_cookies_lwp(r.cookies, filename)

#you can pass a LWPCookieJar directly to requests
requests.get(url, cookies=load_cookies_from_lwp(filename))
25
dtheodor

En développant la réponse de @ miracle2k, les demandes Sessions sont documentées pour fonctionner avec tout cookielibCookieJar. Les LWPCookieJar (et MozillaCookieJar) peuvent enregistrer et charger leurs cookies dans et à partir d'un fichier. Voici un extrait de code complet qui enregistrera et chargera les cookies pour une session de demandes. Le paramètre ignore_discard permet de travailler avec httpbin pour le test, mais vous ne souhaitez peut-être pas l'inclure dans votre code réel.

import os
from cookielib import LWPCookieJar

import requests


s = requests.Session()
s.cookies = LWPCookieJar('cookiejar')
if not os.path.exists('cookiejar'):
    # Create a new cookies file and set our Session's cookies
    print('setting cookies')
    s.cookies.save()
    r = s.get('http://httpbin.org/cookies/set?k1=v1&k2=v2')
else:
    # Load saved cookies from the file and use them in a request
    print('loading saved cookies')
    s.cookies.load(ignore_discard=True)
    r = s.get('http://httpbin.org/cookies')
print(r.text)
# Save the session's cookies back to the file
s.cookies.save(ignore_discard=True)
21
gazpachoking

Cela fera le travail:

session.cookies = LWPCookieJar('cookies.txt')

L'API CookieJar nécessite que vous appeliez manuellement load () et save (). Si vous ne vous souciez pas du format cookies.txt, j'ai une implémentation de ShelvedCookieJar qui persistera lors du changement.

8
miracle2k

J'ai trouvé que les autres réponses avaient des problèmes:

  • Ils ne se sont pas appliqués aux sessions.
  • Ils n'ont pas enregistré et chargé correctement. Seuls le nom et la valeur du cookie ont été enregistrés, la date d'expiration, le nom de domaine, etc. ont tous été perdus.

Cette réponse corrige ces deux problèmes:

import requests.cookies

def save_cookies(session, filename):
    if not os.path.isdir(os.path.dirname(filename)):
        return False
    with open(filename, 'w') as f:
        f.truncate()
        pickle.dump(session.cookies._cookies, f)


def load_cookies(session, filename):
    if not os.path.isfile(filename):
        return False

    with open(filename) as f:
        cookies = pickle.load(f)
        if cookies:
            jar = requests.cookies.RequestsCookieJar()
            jar._cookies = cookies
            session.cookies = jar
        else:
            return False

Ensuite, appelez simplement save_cookies(session, filename) pour enregistrer ou load_cookies(session, filename) pour le charger. Aussi simple que cela.

7
MattClimbs

Je propose un moyen par JSON:

# to save cookie
import json
with open('cookie.txt', 'w') as f:
    json.dump(requests.utils.dict_from_cookiejar(bot.cookies), f)

et

# to load cookie
import json
with open('cookie.txt', 'r') as f:
    cookie = requests.utils.cookiejar_from_dict(json.load(f))
6
Lewis Livermore

Vous pouvez choisir l’objet cookies directement:

cookies = pickle.dumps(session.cookies)

La représentation dict manque beaucoup d'informations: expiration, domaine, chemin ...

Cela dépend de l'utilisation que vous souhaitez faire avec les cookies, mais si vous n'avez pas d'informations sur l'expiration, par exemple, vous devez implémenter la logique permettant de suivre l'expiration manuellement.

Le pickling de l'objet renvoyé par la bibliothèque vous permet de reconstruire facilement l'état, vous pouvez ensuite vous appuyer sur l'implémentation de la bibliothèque.

De toute évidence, de cette façon, le consommateur de l'objet décapé doit utiliser la même bibliothèque

2
JackNova

la réponse de dtheodor a obtenu 95%, sauf que:

session = requests.session(cookies=cookies)

Pour moi, cela soulève une exception en disant que session () ne prend pas d'arguments.

J'ai résolu le problème en prenant les clés/valeurs du cookie.get_dict et en les ajoutant manuellement à la session en utilisant:

session.cookies.set(cookies.keys()[n],cookies.values()[n])
2
gtalarico

code pour python 3

Notez que la grande majorité des cookies sur Internet sont des cookies Netscape. Par conséquent, si vous souhaitez enregistrer les cookies sur le disque au format de fichier Mozilla cookies.txt (également utilisé par les navigateurs Lynx et Netscape), utilisez MozillaCookieJar.

from http.cookiejar import MozillaCookieJar
import requests

s = requests.Session()
s.cookies = MozillaCookieJar('cookies.txt')
# or s.cookies = MozillaCookieJar() and later use s.cookies.filename = 'cookies.txt' or pass the file name to save method.

response = s.get('https://www.msn.com')

s.cookies.save()

le fichier est écrasé s'il existe déjà, supprimant ainsi tous les cookies qu'il contient. Les cookies enregistrés peuvent être restaurés ultérieurement à l'aide des méthodes load () ou revert ().

Notez que la méthode save () ne sauvegardera pas les cookies de session de toute façon, sauf vous demandez autrement en passant un argument true ignore_discard.

s.cookies.save(ignore_discard=True)

en utilisant la méthode de chargement:

charger des cookies à partir d'un fichier.

Les anciens cookies sont conservés sauf s'ils sont remplacés par des nouveaux.

s.cookies.load()

using revert method:

Effacer tous les cookies et recharger les cookies à partir d'un fichier enregistré.

s.cookies.revert()

vous devrez peut-être également passer un argument true ignore_discard dans les méthodes load ou Revert.

note sur l'utilisation de MozillaCookieJar:

Remarque Cela perd des informations sur les cookies RFC 2965 et sur attributs de cookie plus récents ou non standard tels que port.

plus de lecture

0
Sameh Farouk

Un moyen simple de convertir les cookies en liste de dictés et de les enregistrer au format json ou db . Il s'agit de méthodes de classe qui ont l'attribut session.

def dump_cookies(self):
    cookies = []
    for c in self.session.cookies:
        cookies.append({
            "name": c.name,
            "value": c.value,
            "domain": c.domain,
            "path": c.path,
            "expires": c.expires
        })
    return cookies

def load_cookies(self, cookies):
    for c in cookies:
        self.session.cookies.set(**c)

Nous avons seulement besoin de cinq paramètres tels que: name, value, domain, path, expires

0
Mikhail Bulygin