Récupérer les images d’une galerie en python
Rédigé par Fred - - Aucun commentaire
Quand je veux récupérer plusieurs pages, je le fais souvent avec
wget
. L’utilisation des options --load-cookies
, --save-cookies
et --keep-session-cookies
avec --post-data
étant plus que
pratique. Pour parser, ensuite, c’est souvent pénible, même si awk
est là pour aider.
man wget
donne :
# Log in to the server. This can be done only once. wget --save-cookies cookies.txt \ --post-data 'user=foo&password=bar' \ http://server.com/auth.php # Now grab the page or pages we care about. wget --load-cookies cookies.txt \ -p http://server.com/interesting/article.php
Pour parser, j’aime bien python ; je trouve ça plus lisible. Par contre, ce que j’utilisais jusqu’à présent pour me logguer sur une page était moins glop :
import urllib, urllib2, cookielib username = 'foo' password = 'bar' cj = cookielib.CookieJar() handle = urllib2.build_opener(urllib2.HTTPCookieProcessor(cj)) login_data = urllib.urlencode({'username' : username, 'pwd' : password}) handle.open('http://www.example.com/login.php', login_data) res = handle.open('http://www.example.com/my_account.php') print res.read()
Mais ça, c’était avant. Depuis, j’ai découvert Requests. Pour faire un
POST
, c’est aussi simple que :
import requests url= 'http://www.example.com/login.php' login_data = {username = 'myuser', password = 'mypassword'} req = requests.post(url, login_data) page = req.content
Si on a besoin de gérer les cookies, on peut passer par une Session
:
import requests url= 'http://www.example.com' login_data = {username = 'myuser', password = 'mypassword'} s = requests.Session() req = s.post(url + '/login.php', login_data) req = s.get(url + '/my_account.php')
C’est quand même plus lisible, non ?
En fait, récemment, je voulais parcourir les images de la galerie d’un site. Mais cette galerie contenait 10 images seulement par page, pour 40 pages. J’ai donc fait un script pour mettre toutes les images sur une seule page.
Les images sont encapsulées par une balise a class="foo"
et donc
j’utilise BeautifulSoup
pour toutes les lister
(soup.findAll("a","foo")
).
Comme j’ai « besoin » de consulter les images plusieurs fois, j’ai
préféré enregistrer les images en local plutôt que de laisser un lien
sur le site. Pour ça j’ai utilisé stream=True
de la méthode .get
(cf ce lien sur SO).
J’ai pas fait très propre puisque j’affiche la page sur stdout
que
je pipe avec tee
pour mettre dans un fichier. Mais au moins, je vois
si ça marche :þ
# -*- coding: utf-8 -*- from BeautifulSoup import BeautifulSoup from requests import session login_data = { 'login': 'fredtantini', 'password': 'toto1234', 'action': 1 } urlToVisit = 'http://www.example.com' #on ouvre une session with session() as s: #on se connecte req = s.post(urlToVisit + '/login.php', data=login_data) print "<html><body>" #comme je sais qu’il y a 40 pages for nPage in xrange(1,41): #on récupère la page request = s.get(urlToVisit + '/some_page.php?p='+str(nPage)) #que l’on passe à BS soup = BeautifulSoup(request.text) print "<h1> Page - ",nPage,"</h1>" #Pour tous les liens for i in soup.findAll("a","foo"): #on récupère l’image r = s.get(urlToVisit + '/' + i.img['src'], stream=True) #on la télécharge par parties (cf lien SO plus haut) if r.status_code == 200: with open(i.img['alt'] + ".jpg", 'wb') as f: for chunk in r.iter_content(): f.write(chunk) print str(i).replace('./images/', './') print "</body></html>"