2017-10-02 4 views
1

Il y a un site Web que j'ai besoin de gratter, mais avant je dois me connecter.L'authentification donne le code 404

Il semble y avoir trois choses dont j'ai besoin: le nom d'utilisateur, le mot de passe et le jeton d'authenticité. Le nom d'utilisateur et le mot de passe que je connais, mais je ne sais pas comment accéder au jeton.

C'est ce que j'ai essayé:

import requests 
from lxml import html 

login_url = "https://urs.earthdata.nasa.gov/home" 

session_requests = requests.session() 
result = session_requests.get(login_url) 
tree = html.fromstring(result.text) 
authenticity_token = list(set(tree.xpath("//input[@name='authenticity_token']/@value")))[0] 

payload = {"username": "my_name", 
      "password": "my_password", 
      "authenticity_token": authenticity_token} 

result = session_requests.post(
    login_url, 
    data = payload, 
    headers = dict(referer=login_url) 
) 

print (result) 

Il en résulte:

<Response [404]>

Mon nom et mot de passe sont entrés correctement il est donc le jeton qui doit aller mal. Je pense que le problème est cette ligne:

authenticity_token = list(set(tree.xpath("//input[@name='authenticity_token']/@value")))[0]

ou cette ligne:

payload = {"username": "my_name", 
       "password": "my_password", 
       "authenticity_token": authenticity_token} 

en regardant le code source sur la page Web que j'ai remarqué il y a un authenticity_token, csrf-token et csrf-param. Donc, ce sont possibles dans le mauvais ordre, mais j'ai essayé toutes les combinaisons.

EDIT:

Voici une approche belle soupe qui se traduit par 404 à nouveau.

s = requests.session()               
response = s.get(login_url) 

soup = BeautifulSoup(response.text, "lxml")            
for n in soup('input'): 
    if n['name'] == 'authenticity_token':            
     token = n['value'] 
    if n['name'] == 'utf8': 
     utf8 = n['value']            
     break 

auth = {                  
    'username': 'my_username'              
    , 'password': 'my_password'             
    , 'authenticity_token': token  
    , 'utf8' : utf8             
}  

s.post(login_url, data=auth) 

Répondre

1

Si vous inspectez la page, vous remarquerez que la valeur de l'action sous forme est '/login', donc vous devez soumettre vos données à https://urs.earthdata.nasa.gov/login'.

login_url = "https://urs.earthdata.nasa.gov/login" 
home_url = "https://urs.earthdata.nasa.gov/home" 

s = requests.session()               
soup = BeautifulSoup(s.get(home_url).text, "lxml")            
data = {i['name']:i.get('value', '') for i in soup.find_all('input')} 
data['username'] = 'my_username' 
data['password'] = 'my_password' 
result = s.post(login_url, data=data) 

print(result) 

< Réponse [200]>

Un exemple rapide avec selenium:

from selenium import webdriver 

driver = webdriver.Firefox() 
url = 'https://n5eil01u.ecs.nsidc.org/MOST/MOD10A1.006/' 

driver.get(url) 
driver.find_element_by_name('username').send_keys('my_username') 
driver.find_element_by_name('password').send_keys('my_password') 
driver.find_element_by_id('login').submit() 

html = driver.page_source 
driver.quit() 
+0

il y a une autre page que je veux vraiment accéder est 'https: // n5eil01u. ecs.nsidc.org/MOST/MOD10A1.006/'. Après la publication des données sur login_url, y a-t-il un moyen de maintenir la session ou de la republier vers ce lien? Merci de votre aide. –

+0

Si la connexion est réussie, vous devriez pouvoir utiliser la session pour accéder à d'autres pages. Je ne peux pas le vérifier car je n'ai pas encore de compte (il faut jusqu'à 48 heures pour activer de nouveaux comptes) mais vous pouvez essayer avec 'Referer' et 'User-Agent' dans les en-têtes. Si vous ne pouvez toujours pas vous connecter, vous pouvez essayer 'selenium'. –

+0

Oui, je viens d'utiliser 's.get()' à nouveau sur le nouveau lien et j'ai suivi une page de redirection et cela a fonctionné. –