- English
- Français
Mais lorsqu'on a 21 ans, une vie sociale, et qu'on est en juillet, on a pas forcément envie d'aller sur un site toutes les deux heures juste pour trouver du travail. On a même pas forcément internet.
Comme souvent, la solution maline, c'est de scripter, et de laisser aux ordinateurs les tâches répétitives pendant qu'on mange des glaces sous la pluie battante de notre été pourri. Voici donc un petit script Python basé sur la bibliothèque mechanize
, qui est censée simuler le comportement d'un navigateur web. Malheureusement, celle-ci souffre d'une documentation atroce, et il aura fallu tâtonner un peu avant d'arriver à mes fins.
L'idée du script est extrêmement simple : on possède une liste d'identifiants, et pour chacun d'entre eux, on veut se connecter une fois toutes les deux heures.
CREDENTIALS = [ { 'login': "login1", 'password': "pass1", 'name': "Name LASTNAME" }, { 'login': "login2", 'password': "pass2", 'name': "Another NAME" } ] def main(): while True: for cred in CREDENTIALS: connect_to_womanpower(cred) time.sleep(7205) # Two hours = 7200 seconds
Le travail commence vraiment dans la partie suivante. La philosophie de mechanize
est d'émuler un utilisateur qui suivrait les liens hypertextes de la page. On commence donc en se connectant sur le site visé, et on peut ensuite utiliser tout un ensemble de fonctions pour trouver le lien voulu dans la page (en cherchant dans l'URL ou le texte du lien). Par exemple, pour accéder à la page d'identification depuis la page d'accueil, on cliquerait sur le lien "Accédez à votre compte". Ceci se fait en deux lignes de code :
br.open("http://www.womanpower.fr/") br.follow_link(text_regex = r'votre compte')
mechanize
choisit le bon lien et le suit. Pour le suivant, les choses se compliquent : la partie de la page chargée de la saisie des identifiants est incluse depuis une iframe
, afin que celle-ci se fasse en HTTPS (le reste de la page étant en HTTP). Les utilisateurs ne sont pas rassurés par le petit cadenas dans la barre d'adresse, mais au moins, les identifiants transitent de manière chiffrée.
Problème, mechanize
n'inclut pas automatiquement les iframes
dans la page. Pour y accéder, il faut les suivre comme un lien, ce qui est relativement contre-intuitif. On peut alors sélectionner le formulaire, et mettre les bonnes données dans les champs identifiant et mot de passe. Pour trouver le nom du formulaire dans la page, pas de secret : il faut en consulter le code source. Enfin, on soumet le formulaire, et nous voila identifiés !
# Put the credentials and submit. br.select_form(name="formulaire") br["identifiant"] = credentials["login"] br["passwd"] = credentials["password"] response = br.submit()
mechanize
n'est (heureusement) pas capable d'interpréter. On peut donc récupérer l'URL soi-même dans la page à l'aide d'une expression régulière à s'arracher les yeux, et la suivre - et cette fois, le tour est joué.
La facilité avec laquelle on peut automatiser ce genre de tâches laisse cependant rêveur quant à la fiabilité des nombreux sondages réalisés sur internet. On pourrait sans aucun mal enrichir ce script en le branchant sur un petit VPN qui lui permettrait de changer d'adresse IP entre chaque connexion, juste pour le plaisir de se faire élire personne la plus influente de l'année par le magazine Time.
Une solution facile et beaucoup moins rigolote aurait été de se connecter une fois avec Internet Explorer pour obtenir le cookie d'identification, et d'utiliser le Task Scheduler de Windows (si vous connaissez cron, vous n'avez probablement pas besoin de ce script) pour se connecter sur la bonne URL à intervalles réguliers.
Pour archive, voici le script final. N'oubliez pas que ces approches peu élégantes, dites de scraping, sont susceptibles de cesser de fonctionner à tout changement sur le site cible !
""" (c) 2012 Ivan Kwiatkowski This is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This source code is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this source code. If not, see http://www.gnu.org/licenses/. """ from datetime import datetime import os import sys import re import time import mechanize URL_REGEXP = "(https?:((//)|(\\\\))+[\w\d:#@%/;$()~_?\+-=\\\.&]*)" # Don't even try. CREDENTIALS = [ { 'login': "login1", 'password': "pass1", 'name': "Name LASTNAME" }, { 'login': "login2", 'password': "pass2", 'name': "Another NAME" } ] def main(): while True: try: for cred in CREDENTIALS: connect_to_womanpower(cred) time.sleep(7205) # Two hours = 7200 seconds except KeyboardInterrupt: print "[*] Thank you for using this script :)" break def connect_to_womanpower(credentials): """ Connects to the Womanpower website using the given credentials. """ try: br = mechanize.Browser() br.addheaders = [('User-agent', 'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1)')] # Use a standard user-agent br.open("http://www.womanpower.fr/") br.follow_link(text_regex = r'votre compte') br.follow_link(url_regex = r'connexionInterimaire') # Put the credentials and submit. br.select_form(name="formulaire") br["identifiant"] = credentials["login"] br["passwd"] = credentials["password"] response = br.submit() # This step needs a little handiwork since the JavaScript redirection is not supported by mechanize. redirect_url = re.search(URL_REGEXP, response.read()).group(0) final_page = br.open(redirect_url) # Check that the name of the user is in the final page (just to make sure everything went well). if credentials["name"] in final_page.read(): print "[*] %s: %s logged in successfully!" % (datetime.now(), credentials["name"]) else: print "[!] %s: could not log %s in!" % (datetime.now(), credentials["name"]) except Exception: print "[!] %s: Exception while logging in %s!\n Please report this to Ivan." % (datetime.now(), credentials["name"]) if __name__ == "__main__": main()