Python - automatyczne logowanie na stronie

0

Cześć.
Mam drobny problem. Sprawa jest bardzo ciekawa.
Chciałbym za pomocą skryptu w Pythonie zalogować się na stronę www, a następnie pobrać jej kod źródłowy.
Aktualnie zatrzymałem się w takim miejscu, że kod źródłowy jest pobierany, ale tylko strony głównej, a mi zależy na kodzie strony dostępnej po zalogowaniu.

Część kodu źródłowego strony www:

<form method="post" action="/adres_docelowy">
   <input type="hidden" name="NAZWA" value="WARTOSC">
       <tr>
          <td align="center"><INPUT TYPE="text" name="login" value="" maxlength="50" size="30" CLASS="UZYTKOWNIK">  </td>
       </tr>
       <tr>
         <td CLASS="INFO" valign="middle" height="20">&nbsp;&nbsp;&nbsp;Hasło:  </td>
       </tr>
       <tr>
           <td align="center"><INPUT TYPE="password" name="password" value="" maxlength="20" size="30" CLASS="HASLO">    </td>
       </tr>
       <tr>
            <td align="center"><input type="submit" value=" " CLASS="BUTTON_ZALOGUJ" title="Zaloguj">     </td>
       </tr>
       <tr>
             <td align="center"><input type="submit" onClick="form.action='przypomnij'" CLASS="BUTTON_ZAPOMNIALEM" title="Zapomniałem hasła" value=" ">           </td>
       </tr>
</form>

Kod źródłowy skryptu w Pythonie:

import cookielib
import urllib
import urllib2


# Store the cookies and create an opener that will hold them
cj = cookielib.CookieJar()
opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cj))

# Add our headers
opener.addheaders = [('User-agent', 'JestemAgentem')]

# Install our opener (note that this changes the global opener to the one
# we just made, but you can also just call opener.open() if you want)
urllib2.install_opener(opener)

# The action/ target from the form
authentication_url = 'https://adres.com'

# Input parameters we are going to send
payload = {
  'NAZWA': 'WARTOSC',
  'UZYTKOWNIK': 'aaa',
  'HASLO': 'bbb'
  }

# Use urllib to encode the payload
data = urllib.urlencode(payload)

# Build our Request object (supplying 'data' makes it a POST)
req = urllib2.Request(authentication_url, data)

# Make the request and read the response
resp = urllib2.urlopen(req)
contents = resp.read()

print "opening file..."
plik = open('zrodlo.txt','w+')
plik.write(contents)
plik.close
print "done"

Wynikiem jest pobranie tylko kodu źródłowego strony głównej, nie ma informacji o błędnym haśle, więc najprawdopodobniej nie zostało zainicjowane wciśnięcie przycisku.
Zastanawiam się, co jeszcze mogę zmodyfikować w kodzie.
PS. Próbowałem również zrobić logowanie w C++, ale nie udało mi się napisać kodu pobierającego źródło strony po zalogowaniu (próbowałem z libCURL).
Gdyby ktoś posiadał jakiś sprawdzony kod i chciałby udostępnić, to bardzo proszę się pochwalić.
Z góry dziękuję za pomoc.
Jarek

0

A probowales odpalic jakikolwiek sniffer i sprawdzic co rzeczywiscie leci do tego serwera i co rzeczywiscie ten serwer zwraca, czy tak sie bawisz po macoszemu?

0

Sprawdzam odpowiedzi po stronie serwera w pliku źródłowym www.
Przeważnie jest tam "Twoja sesja wygasła"

W snifferze web otrzymałem takie informacje:
Strona ustawia ciasteczka:
Set-Cookie:SESSIONID=105351f07.....Ae; path=/strona
Set-Cookie:jbo.ApplicationCookie.KonfiguracjaServiceDataControl={904}053E.....7D64507
Natomiast w źródle strony jest napisane: strona nie jest dostępna.

To dziwne, podczas normalnego logowania na stronie przechwytywałem pakiety Wiresharkiem.
Normalnie się zalogowałem, jednak w Wiresharku żadnego pakietu POST nie widzę.

1

Z tego co widze po prostu zle dane wysylasz. Musisz brac pola name z inputow. Jak to ci pomoze masz dzialajacy kod:

/flask-app.py -> odpalasz python3 flask-app.py (nie sprawdzalem na 2)

from flask import Flask
from flask import render_template, request, session, redirect, escape, url_for
app = Flask(__name__)


@app.route('/')
def index():
    if 'username' in session:
        return 'Logged as {}.'.format(escape(session['username']))
    return 'You are not logged in'


@app.route('/login', methods=['GET', 'POST'])
def login():
    error = None
    if request.method == 'POST':
        if valid_login(request.form['username'],
                       request.form['password']):
            session['username'] = request.form['username']
            return redirect(url_for('index'))
        else:
            error = 'Invalid username/password'

    return render_template('login.html', error=error)


def valid_login(name, passw):
    return name == 'ziutek' and passw == 'tajne123'


@app.route('/logout')
def logout():
    session.pop('username', None)
    return redirect(url_for('index'))


if __name__ == '__main__':
    app.secret_key = 't4jn3Has3lko'
    app.run(debug=True)

/templates/login.html

<!DOCTYPE html>
<html>
<head>
  <title>Login</title>
  <meta charset="utf-8" />
</head>
<body>
  {% if error %}
    <h1>{{ error }}</h1>
  {% endif %}

  <form action="login" method="post">
    <p><input type="text" name="username" /></p>
    <p><input type="text" name="password" /></p>
    <p><input type="submit" value="Log in" /></p>
  </form>
</body>
</html>

/login.py -> odpalasz python2 login.py url username password (domyslnie dla tej appki co wrzucilem - url: http://127.0.0.1:5000/login, username: ziutek, password: tajne123)

import cookielib
import urllib
import urllib2
import sys


def set_opener():
    cookie_jar = cookielib.CookieJar()
    opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cookie_jar))
    urllib2.install_opener(opener)


def build_request(login_url, username, passwd):
    body = urllib.urlencode({
        'username': username,
        'password': passwd
    })
    return urllib2.Request(login_url, body)


def send_request(req):
    return urllib2.urlopen(req)


def main(args):
    set_opener()
    req = build_request(*args)
    resp = send_request(req)
    print(resp.read())


if __name__ == '__main__':
    if len(sys.argv) > 3:
        main(sys.argv[1:])
0

@n0name_l, dziękuję za konkretną odpowiedź, jednak kod działa tak samo jak mój, tzn. widoczny jest komunikat: "Twoja sesja wygasła. Zaloguj się ponownie", czyli jest chyba jakiś problem z ciasteczkami. Nie mogę sobie z tym poradzić. :(

1
import cookielib
import urllib
import urllib2
import sys
from bs4 import BeautifulSoup


def set_opener():
    cookie_jar = cookielib.CookieJar()
    opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cookie_jar))
    urllib2.install_opener(opener)


def build_request(url, username, passwd, token_name, token):
    body = urllib.urlencode({
        token_name: token,
        'login': username,
        'password': passwd
    })
    return urllib2.Request(url, body)


def send_request(req):
    return urllib2.urlopen(req)


def extract_token(page, token_name):
    soup = BeautifulSoup(page)
    second = soup.find(attrs={'name': token_name})['value']
    return second


def main(args):
    url, login, password = args[0], args[1], args[2]
    token_name = args[5]
    set_opener()
    page = send_request(url+args[3]).read()
    token = extract_token(page, token_name)
    req = build_request(url+args[4], login, password, token_name, token)
    resp = send_request(req)
    print('{}\n\n{}'.format(resp.info(), resp.read()))

if __name__ == '__main__':
    if len(sys.argv) > 6:
        main(sys.argv[1:])

Odpalasz python2 app.py <domena> <login> <haslo> <sciezka_do_strony_startowej> <sciezka_do_strony_logowania> <nazwa_tokena>

Jeszcze mala uwaga: uzylem tutaj BeautifulSoup4 (dostepny przez pipa, badz w repo twojej dystrybucji).

1 użytkowników online, w tym zalogowanych: 0, gości: 1