Ceci est un suivi d'une question que j'ai vue plus tôt aujourd'hui. Dans cette question, un utilisateur demande à un problème de télécharger un pdf de cette url:Téléchargement de fichier avec urllib2 vs demandes: Pourquoi ces sorties sont-elles différentes?
http://journals.sagepub.com/doi/pdf/10.1177/0956797614553009
Je pense que les deux fonctions de téléchargement ci-dessous va donner le même résultat, mais la version urllib2
télécharge, html avec tag de script référençant un chargeur pdf, tandis que la version requests
télécharge le pdf réel. Quelqu'un peut-il expliquer la différence de comportement?
import urllib2
import requests
def get_pdf_urllib2(url, outfile='ex.pdf'):
resp = urllib2.urlopen(url)
with open(outfile, 'wb') as f:
f.write(resp.read())
def get_pdf_requests(url, outfile='ex.pdf'):
resp = requests.get(url)
with open(outfile, 'wb') as f:
f.write(resp.content)
est-requests
assez intelligent pour attendre des sites Web dynamiques pour rendre avant de télécharger?
Modifier Faisant suite à l'idée de @ cwallenpoole, j'ai comparé les en-têtes et essayé la permutation des en-têtes de la requête requests
dans la demande urllib2
. L'en-tête magique était Cookie; les fonctions ci-dessous écrivent le même fichier pour l'exemple d'URL.
def get_pdf_urllib2(url, outfile='ex.pdf'):
req = urllib2.request(url, headers={'Cookie':'I2KBRCK=1'})
resp = urllib2.urlopen(req)
with open(outfile, 'wb') as f:
f.write(resp.read())
def get_pdf_requests(url, outfile='ex.pdf'):
resp = requests.get(url)
with open(outfile, 'wb') as f:
f.write(resp.content)
question suivante: où est-ce cookie requests
obtenir? Est-ce que requests
effectue plusieurs voyages vers le serveur?
Edit 2 Cookie est venu d'un en-tête de redirection:
>>> handler=urllib2.HTTPHandler(debuglevel=1)
>>> opener=urllib2.build_opener(handler)
>>> urllib2.install_opener(opener)
>>> respurl=urllib2.urlopen(req1)
send: 'GET /doi/pdf/10.1177/0956797614553009 HTTP/1.1\r\nAccept-Encoding: identity\r\nHost: journals.sagepub.com\r\nConnection: close\r\nUser-Agent: Python-urllib/2.7\r\n\r\n'
reply: 'HTTP/1.1 302 Found\r\n'
header: Server: AtyponWS/7.1
header: P3P: CP="NOI DSP ADM OUR IND OTC"
header: Location: http://journals.sagepub.com/doi/pdf/10.1177/0956797614553009?cookieSet=1
header: Set-Cookie: I2KBRCK=1; path=/; expires=Thu, 14-Dec-2017 17:28:28 GMT
header: Content-Type: text/html; charset=utf-8
header: Content-Length: 110
header: Connection: close
header: Date: Wed, 14 Dec 2016 17:28:28 GMT
send: 'GET /doi/pdf/10.1177/0956797614553009?cookieSet=1 HTTP/1.1\r\nAccept-Encoding: identity\r\nHost: journals.sagepub.com\r\nConnection: close\r\nUser-Agent: Python-urllib/2.7\r\n\r\n'
reply: 'HTTP/1.1 302 Found\r\n'
header: Server: AtyponWS/7.1
header: Location: http://journals.sagepub.com/action/cookieAbsent
header: Content-Type: text/html; charset=utf-8
header: Content-Length: 85
header: Connection: close
header: Date: Wed, 14 Dec 2016 17:28:28 GMT
send: 'GET /action/cookieAbsent HTTP/1.1\r\nAccept-Encoding: identity\r\nHost: journals.sagepub.com\r\nConnection: close\r\nUser-Agent: Python-urllib/2.7\r\n\r\n'
reply: 'HTTP/1.1 200 OK\r\n'
header: Server: AtyponWS/7.1
header: Cache-Control: no-cache
header: Pragma: no-cache
header: X-Webstats-RespID: 8344872279f77f45555d5f9aeb97985b
header: Set-Cookie: JSESSIONID=aaavQMGH8mvlh_-5Ct7Jv; path=/
header: Content-Type: text/html; charset=UTF-8
header: Connection: close
header: Transfer-Encoding: chunked
header: Date: Wed, 14 Dec 2016 17:28:28 GMT
header: Vary: Accept-Encoding
Vous êtes sur la bonne voie - J'ai réussi à faire fonctionner la version d'urllib2 en ajustant les en-têtes. Il ne s'agissait pas d'un agent utilisateur, mais d'un cookie manquant. Je vais éditer ma question, parce que maintenant je suis curieux d'où vient le cookie. – nrlakin
Cela provient probablement d'un en-tête 'redirect': http://www.diveintopython.net/http_web_services/redirects.html – cwallenpoole
C'était tout. La version 302 d'urllib2 avec un en-tête Set-Cookie, puis renvoie une page d'erreur pour "No Cookie Set". – nrlakin