2010-10-13 5 views
14

Je suis nouveau à Python et je reçois cette erreur:IndentationError: erreur tiret inattendu

Traceback (most recent call last): 
    File "/usr/local/bin/scrapy", line 4, in <module> 
    execute() 
    File "/opt/local/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/scrapy/cmdline.py", line 130, in execute 
    _run_print_help(parser, _run_command, cmd, args, opts) 
    File "/opt/local/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/scrapy/cmdline.py", line 96, in _run_print_help 
    func(*a, **kw) 
    File "/opt/local/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/scrapy/cmdline.py", line 136, in _run_command 
    cmd.run(args, opts) 
    File "/opt/local/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/scrapy/commands/crawl.py", line 42, in run 
    q = self.crawler.queue 
    File "/opt/local/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/scrapy/command.py", line 31, in crawler 
    self._crawler.configure() 
    File "/opt/local/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/scrapy/crawler.py", line 36, in configure 
    self.spiders = spman_cls.from_settings(self.settings) 
    File "/opt/local/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/scrapy/spidermanager.py", line 33, in from_settings 
    return cls(settings.getlist('SPIDER_MODULES')) 
    File "/opt/local/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/scrapy/spidermanager.py", line 23, in __init__ 
    for module in walk_modules(name): 
    File "/opt/local/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/scrapy/utils/misc.py", line 65, in walk_modules 
    submod = __import__(fullpath, {}, {}, ['']) 
    File "/my_crawler/empt/empt/spiders/empt_spider.py", line 59 
    check_exists_sql = "SELECT * FROM LINKS WHERE link = '%s' LIMIT 1" % item['link'] 
    ^
IndentationError: unexpected indent 

Sur ce morceau de code:

def parse_item(self, response): 
    hxs = HtmlXPathSelector(response) 
    sites = hxs.select('//a[contains(@href, ".mp3")]/@href').extract() 
    items = [ ] 

    #for site in sites: 
     #link = site.select('a/@href').extract() 
     #print site 
    for site in sites: 
     item = EmptItem() 
     item['link'] = site #site.select('a/@href').extract() 

     #### DB INSERT ATTEMPT ### 
     #MySQL Test 

     #open db connection 
     db = MySQLdb.connect("localhost","root","str0ng","TESTDB") 

     #prepare a cursor object using cursor() method 
     cursor = db.cursor() 

     #see if any links in the DB match the crawled link 
     check_exists_sql = "SELECT * FROM LINKS WHERE link = '%s' LIMIT 1" % item['link'] 

     cursor.execute(check_exists_sql) 

     if cursor.rowcount = 0: 
      #prepare SQL query to insert a record into the db. 
      sql = "INSERT INTO LINKS (link) VALUES ('%s')" % item['link'] 

      try: 
       #execute the sql command 
       cursor.execute(sql) 
       #commit your changes to the db 
       db.commit() 
      except: 
       #rollback on error 
       db.rollback() 

       #fetch a single row using fetchone() method. 
       #data = cursor.fetchone() 

       #print "Database version: %s " % data 

      #disconnect from server 
      db.close() 

      ### end mysql 

     items.append(item) 
    return items​ 
+1

http://docs.python.org/tutorial/introduction.html: « chaque ligne dans un bloc de base doit être en retrait de la même quantité ». (Une mauvaise utilisation du terme « bloc de base », soit dit en passant ...) –

+3

Comment traiter 'IndentationError': 1) Assurez-vous que vos lignes sont en retrait correctement, se souvenant que Python pense que les taquets de tabulation sont toutes les 8 colonnes. 2) Recherchez un deux-points manquant sur la ligne ci-dessus, qui est généralement un type de ligne 'for',' if', 'else',' while', 'try' ou similaire. En général, si une ligne se termine par deux points, la ligne suivante avec le code doit être indentée d'une certaine quantité. –

+0

Désolé, je ne l'ai pas collé correctement dans le débordement de la pile, je l'ai corrigé maintenant pour correspondre à mon code. – ian

Répondre

35

Alors que les erreurs d'indentation sont évidentes dans la page StackOverflow, ils peuvent ne pas être dans votre éditeur. Vous avez ici un mélange de différents types d'indentation, 1, 4 et 8 espaces. Vous devez toujours utiliser quatre espaces pour l'indentation, selon PEP8. Vous devriez également avoid mixing tabs and spaces.

Je recommande également que vous essayez d'exécuter votre script en utilisant le '-tt' command-line option pour déterminer quand vous mélangez accidentellement des onglets et des espaces. Bien sûr, tout éditeur décent sera en mesure de mettre en évidence les onglets par rapport aux espaces (tels que Vim's 'list' option).

+0

Il n'y a rien de mal à mélanger les tabulations et les espaces (bien que Python3, dans un ajustement de braindamage, jette une erreur si vous le faites).Cependant, vous ne devriez jamais, jamais définir la largeur d'un caractère de tabulation à tout sauf 8 espaces; c'est simplement la définition de^I. –

+1

@Glenn: La définition de TAB n'est pas de 8 espaces, c'est "move to the tabstop". Vous avez en partie raison de dire qu'il n'y a rien de mal à mélanger les onglets et les espaces, mais seulement si personne d'autre ne regarde votre code. Je travaille avec beaucoup de gens qui utilisent des largeurs de tabulation hérétiques, et la seule façon de faire face est d'utiliser uniquement des espaces pour l'indentation. –

+0

@Matt: un tabulateur dans un fichier de texte brut comporte 8 caractères; Tout le reste est faux. Cela ne veut pas dire que indenter * code * par d'autres montants est faux, bien sûr, mais c'est complètement indépendant de ce que le caractère^I signifie. La solution correcte consiste à dire aux utilisateurs de corriger leurs taquets de tabulation, ce qui n'est pas plus difficile (plus facile dans la plupart des éditeurs) que de désactiver les tabulations. –

3

L'indentation est faux, comme l'erreur vous dit. Comme vous pouvez le voir, vous avez indenté le code commençant par la ligne indiquée trop peu pour être dans la boucle for, mais trop pour être au même niveau que la boucle. Python voit l'absence d'indentation comme la fin de la boucle for, puis se plaint que vous avez trop indenté le reste du code. (La ligne def Je parie est juste un artefact de la façon dont Stack Overflow vous souhaite formater votre code.)

Edit: Compte tenu de votre correction, je parie que vous avez un mélange des onglets et des espaces dans la fichier source, de sorte qu'il regarde à l'œil humain comme le code s'aligne, mais Python ne le considère pas. Comme d'autres l'ont suggéré, utiliser uniquement des espaces est la pratique recommandée (voir PEP 8). Si vous démarrez Python avec python -t, vous obtiendrez des avertissements s'il existe des onglets et des espaces mixtes dans votre code, ce qui devrait vous aider à identifier le problème.

+0

Les deux où réellement causé par le débordement de la pile, je l'ai fait afficher correctement maintenant. – ian

1

L'erreur est assez simple - la ligne commençant par check_exists_sql n'est pas correctement en retrait. D'après le contexte de votre code, j'indentera et les lignes suivantes pour correspondre à la ligne avant qu'il:.

#open db connection 
    db = MySQLdb.connect("localhost","root","str0ng","TESTDB") 

    #prepare a cursor object using cursor() method 
    cursor = db.cursor() 

    #see if any links in the DB match the crawled link 
    check_exists_sql = "SELECT * FROM LINKS WHERE link = '%s' LIMIT 1" % item['link'] 

    cursor.execute(check_exists_sql) 

Et gardez indenter jusqu'à la fin de la boucle for (tout le chemin jusqu'à et y compris items.append(item)