Seite 1 von 1

Login mit Mechanize - Probleme

Verfasst: Donnerstag 22. Januar 2009, 18:20
von vogti
Hallo,
ich möchte mich auf einer Website einloggen und habe dazu folgenden Code geschrieben:

Code: Alles auswählen

#! /usr/bin/python
# -*- coding: utf-8 -*-
from mechanize import Browser

#response = mechanize.urlopen('http://www.twitter.com/')
#print response.geturl()
#response.close()

br=Browser()
br.open('http://www.twitter.com')
assert br.viewing_html()
print br.title()

br.select_form(name="signin")
br['daten']=['(username)','(password)']
response2=br.submit()
print response2.geturl()
print response2.info()
print response2.read()
Bekomme jedoch immer folgende Ausgabe:

Code: Alles auswählen

Twitter: What are you doing?
Traceback (most recent call last):
  File "/home/vogti/python/Dateiarbeit/teil4.py", line 14, in <module>
    br.select_form(name="signin")
  File "build/bdist.linux-i686/egg/mechanize/_mechanize.py", line 530, in select_form
    raise FormNotFoundError("no form matching "+description)
FormNotFoundError: no form matching name 'signin'
Was habe ich da falsch gemacht?

Da ich den Fehler nicht finden konnte, habe ich geprüft, ob Mechanize richtig installiert habe. Das habe ich mit sudo python functional_tests.py getan und diese Ausgabe bekommen. Kann das ganze vielleicht damit zusammen hängen? Warum kommt dieser Fehler?

lg,
vogti

Verfasst: Donnerstag 22. Januar 2009, 18:29
von DasIch
Es gibt kein "signin" Formular auf der Seite.

Verfasst: Donnerstag 22. Januar 2009, 18:32
von vogti
DasIch hat geschrieben:Es gibt kein "signin" Formular auf der Seite.
Ich war der Meinung, dass dieses Stück hier gemeint ist:

Code: Alles auswählen

            <form method="post" id="signin" action="https://twitter.com/sessions">
          
            <input id="authenticity_token" name="authenticity_token" type="hidden" value="e9f9207c6669013a559ac6a1a72c2a1804838365" />            <fieldset class="common-form standard-form">
              <legend>Please sign in</legend>
              <p>

                <label class="inside" tabindex="1" for="username">user name or email address:</label>
                <input type="text" id="username" name="session[username_or_email]" value="" title="username"  />
              </p>
              <p>
                <label class="inside" tabindex="2" for="password">password:</label>
                <input type="password" id="password" name="session[password]" value="" title="password" />
              </p>
              <p class="remember">

                <input type="checkbox" id="remember" name="remember_me" value="1" />
                <label for="remember">Remember me</label>
              </p>
              <p class="submit">
                <input type="submit" id="signin_submit" value="Sign In »" />
              </p>
              <p class="forgot">
                Forgot password?                <a id="resend_password_link" href="/account/resend_password">Click here</a>.
              </p>

              <p class="complete">
                Already using Twitter from your phone?                <a href="/account/complete" id="account_complete_link">Click here.</a>
              </p>
            </fieldset>
          </form>
id="signin" - Das ist doch gemeint, oder?

Verfasst: Donnerstag 22. Januar 2009, 18:41
von tordmor
Vermutlich ist ein name-Attribut gemeint, nicht id.

Verfasst: Donnerstag 22. Januar 2009, 18:46
von snafu
Probier's mal so:

Code: Alles auswählen

In [8]: from mechanize import Browser

In [9]: br = Browser()

In [10]: br.open('http://www.twitter.com')
Out[10]: <response_seek_wrapper at 0x8dcec4c whose wrapped object = <closeable_response at 0x8dc904c whose fp = <socket._fileobject object at 0x8dc5f0c>>>

In [11]: br.select_form(nr=1)

In [12]: br['session[username_or_email]'] = 'musst_du_wissen'

In [13]: br['session[password]'] = 'dies auch'

In [14]: br.submit()
Out[14]: <response_seek_wrapper at 0x8dcec2c whose wrapped object = <closeable_response at 0x8dccf2c whose fp = <socket._fileobject object at 0x8dc5b1c>>>
Du solltest solche Sachen besser vorher durch den Parser jagen. Der zeigt dir dann auch den Index für das richtige Formular in der Liste an.

Verfasst: Donnerstag 22. Januar 2009, 19:43
von vogti
snafu hat geschrieben:Probier's mal so:

Code: Alles auswählen

In [8]: from mechanize import Browser

In [9]: br = Browser()

In [10]: br.open('http://www.twitter.com')
Out[10]: <response_seek_wrapper at 0x8dcec4c whose wrapped object = <closeable_response at 0x8dc904c whose fp = <socket._fileobject object at 0x8dc5f0c>>>

In [11]: br.select_form(nr=1)

In [12]: br['session[username_or_email]'] = 'musst_du_wissen'

In [13]: br['session[password]'] = 'dies auch'

In [14]: br.submit()
Out[14]: <response_seek_wrapper at 0x8dcec2c whose wrapped object = <closeable_response at 0x8dccf2c whose fp = <socket._fileobject object at 0x8dc5b1c>>>
Du solltest solche Sachen besser vorher durch den Parser jagen. Der zeigt dir dann auch den Index für das richtige Formular in der Liste an.
Dein code sieht ja abenteuerlich aus... Wo hastn das herkopiert? :shock:
Meins sieht jetzt so aus und funktioniert scheinbar - danke =)

Code: Alles auswählen

#! /usr/bin/python
# -*- coding: utf-8 -*-
from mechanize import Browser

#response = mechanize.urlopen('http://www.twitter.com/')
#print response.geturl()
#response.close()

br=Browser()
br.open('http://www.twitter.com')
assert br.viewing_html()
print br.title()

br.select_form(nr=1)
br['session[username_or_email]']=(username)
br['session[password]']=(password)
response2=br.submit()
print response2.geturl()
print response2.info()
print response2.read()
Was genau macht das nr=1 im br.select_form()?

Edit:
Wie kann ich die Autorisierungsdaten übermitteln, wenn ich zum Beispiel einen solchen Link habe? Den Link habe ich irgendwo aus der TwitterAPI - die Daten muss man doch trotzdem übergeben können, oder?
Der Link: http://twitter.com/statuses/update.xml

Verfasst: Donnerstag 22. Januar 2009, 20:15
von Leonidas
vogti hat geschrieben:Dein code sieht ja abenteuerlich aus... Wo hastn das herkopiert? :shock:
Das ist einfach die Ausgabe von IPython.

Verfasst: Donnerstag 22. Januar 2009, 20:31
von Dauerbaustelle
[Offtopic]
Mal abgesehen davon, dass *ziemlich* doof ist, seine Zugangsdaten im Internet zu veröffentlichen, ist das von dir verwendete Passwort "Mariuri" sehr schwach und schnell zu knacken.
Mit einer anständigen Brute-Force-Attacke (welche auf twitter.com nicht ohne weiteres angewendet werden kann) wäre dein Passwort in weniger als einer Millisekunde berechnet, wenn man mal davon ausgeht, dass wir es mit den fast überall genutzten md5-Hashes zu tun haben.

Besser wäre ein Passwort, welches Groß-, Kleinbuchstaben, Zahlen und Sonderzeichen enthält sowie für jeden Service/jede Domain variiert. Es könnte zB nach einem Schema aufgebaut sein, wie etwa
Zeichenkette1_ServiceabhängigeZeichenkette_Zeichenkette2

Kleines Beispiel:

Code: Alles auswählen

Zeichenkette1 = UI7@9%
ServiceZK = Jeder dritte Buchstabe des Namens + Länge des Namens (im Falle Twitter: ie7)
Zeichenkette2 = p0!
Das Passwort für Twitter sähe dann so aus:

Code: Alles auswählen

UI7@9%ie7p0!
und für Google so:

Code: Alles auswählen

UI7@9%oe6p0!

(btw: ich habe dein Passwort extra hier nochmals gepostet, damit zu gezwungen bist, es zu ändern =))
[/Offtopic]

Verfasst: Donnerstag 22. Januar 2009, 20:54
von vogti
@Dauerbaustelle ufff - peinlich. Habe ich vergessen herauszueditieren. Danke für deine kleine Ausführung zu Erstellung des perfekten Passworts. Wäre dir dennoch dankbar, wenn du es herauseditieren würdest =) - geändert ist es bereits ;)

Verfasst: Freitag 23. Januar 2009, 00:35
von snafu
vogti hat geschrieben:Was genau macht das nr=1 im br.select_form()?
Mechanize erstellt eine Liste mit allen Formularen auf der Seite, die man ihm gibt. Mit Hilfe von ParseResponse (siehe Link) kannst du die Liste durchgehen und gucken welchen Index das von dir gewünschte Formular hat. Das steuerst du dann mit nr an.