web-dev-qa-db-fra.com

IndentationError: erreur de retrait inattendue

Je suis nouveau sur Python et j'obtiens cette erreur:

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​
18
ian

Bien que les erreurs d'indentation soient évidentes dans la page StackOverflow, elles peuvent ne pas figurer dans votre éditeur. Vous avez un mélange de différents types d'indentation ici, 1, 4 et 8 espaces. Vous devez toujours utiliser quatre espaces pour l'indentation, comme indiqué dans PEP8 . Vous devriez également éviter de mélanger des tabulations et des espaces

Je vous recommande également d'essayer d'exécuter votre script à l'aide de l'option de ligne de commande '-tt' pour déterminer le moment où vous mélangez accidentellement des onglets et des espaces. Bien sûr, tout bon éditeur pourra mettre en surbrillance les tabulations par rapport aux espaces (comme l'option 'list' de Vim ).

39
Johnsyweb

L'indentation est fausse, comme le dit l'erreur. Comme vous pouvez le constater, vous avez trop peu inséré le code commençant par la ligne indiquée pour être dans la boucle for, mais trop pour être au même niveau que la boucle for. Python considère le manque d'indentation comme mettant fin à la boucle for, puis se plaint que vous ayez trop indenté le reste du code. (La ligne def que je parie est juste un artefact de la façon dont Stack Overflow veut que vous formatiez votre code.)

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

3
kindall

L'erreur est assez simple: la ligne commençant par check_exists_sql n'est pas mise en retrait correctement. Dans le contexte de votre code, je l'indenterais et les lignes suivantes pour correspondre à la ligne précédente:

   #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 continuez à l'indenter jusqu'à la fin de la boucle for (jusqu'à items.append(item) et y compris.

1
Chris Bunch

Comme l'erreur indique que le code n'est pas correctement mis en retrait, check_exists_sql n'est pas aligné avec la ligne située au-dessus de celle-ci cursor = db.cursor().

Utilisez également 4 espaces pour l'indentation.

Lisez ceci http://diveintopython.net/getting_to_know_python/indenting_code.html

0
Anurag Uniyal