1
votes

Comment corriger l'erreur «Index de liste hors limites»

Je racle une page Web et j'écris la sortie dans un fichier .csv. J'obtiens une erreur "index de liste hors limites". Je pense que je comprends ce que signifie l'erreur, mais je ne sais pas comment la corriger.

Le code HTML qui héberge les conteneurs sur lesquels je veux itérer ressemble à ceci:

booth_number = cols[3].text


8 commentaires

la ligne 5 semble commencer par une balise non autorisée et aucune balise correspondante précédente. Cela cause-t-il votre erreur?


Êtes-vous sûr à 100% que container.findAll ("td") renverra toujours une liste dont la longueur est de 4 ou plus? Si tel est le cas, pouvez-vous le confirmer en ajoutant print (len (cols)) juste après cette ligne? Sinon, que doit-il se passer lorsque cols est trop court? (Autre que s'écraser)


Cet exemple de HTML a un avec six enfants, mais il doit y avoir d'autres éléments dans le HTML complet avec trop peu de s.


Bizarrement, votre code fonctionne bien pour moi. Py3 et BS4. Cela implique que votre page_html n'a pas toujours le nombre de que vous attendez, comme d'autres l'ont suggéré


Merci a tous. Je pense que cela a du sens pour moi. Il y a d'autres conteneurs dans le HTML qui n'ont pas le même nombre de , n'est-ce pas? Et je peux résoudre ce problème en utilisant len (cols) ?


@Kevin J'obtiens "7" quand j'ajoute print (len (cols)) après cols = container.findAll ("td")


Vous devez répondre à la question "Qu'est-ce que je veux faire s'il y a moins de six colonnes dans la ligne actuelle?" Voulez-vous ignorer complètement la ligne ou voulez-vous récupérer ce que vous pouvez et utiliser des valeurs d'espace réservé pour le reste?


@JohnGordon Je pense que je veux aller chercher ce que je peux et utiliser un numéro d'espace réservé pour le reste.


3 Réponses :


0
votes

Il n'y a pas autant de colonnes que vous le supposez.

Vous pouvez voir combien de colonnes il y a avec len (cols) , et en fonction de cela, décider quoi faire lorsque cette colonne attendue n'est pas là.

Notez que vous rencontrerez un problème similaire avec la ligne qui suit.


0 commentaires

1
votes

Le problème est que le tableau cols a une longueur inférieure à l'élément auquel vous essayez d'accéder. Dans l'exemple

if len(cols) > 3:
     booth_number = cols[3].text

le tableau cols a une longueur de 3 ou moins car l'indexation du tableau est de base zéro (l'élément 1 a un index de 0). Lorsque vous essayez d'accéder au quatrième élément avec un index de 3, vous accédez à un élément en dehors de la plage.

Vous pouvez remédier à cela en vérifiant la longueur avant d'accéder à l'élément.

booth_number = cols[3].text

de cette façon, si le numéro de stand n'est pas dans les cols, votre programme n'échoue pas et ne s'arrête pas.


5 commentaires

Cela dépend, vous pouvez l'ajouter avant chaque accès au tableau cols, donc vous auriez si len (cols)> 1: company_name = cols [1] .find ("a"). Text si len (cols)> 2: numéro_booth = cols [2] .text ... etc. Ou, si l'enregistrement est inutile sans toutes les colonnes, vous pouvez simplement vérifier la longueur complète avant de traiter la ligne, afin que vous puissiez obtenir vos colonnes avec cols = container.findAll ("td") puis faire un if len ( cols)> 5: récupérez vos données.


Donc: `` `pour conteneur dans des conteneurs: cols = container.findAll (" td ") if len (cols)> 1: company_name = cols [1] .find (" a "). Text if len (cols)> 2 : booth_number = cols [2] .text si len (cols)> 3: category = cols [3] .text.strip () if len (cols)> 5: country = cols [5] .text ''


Lorsque j'ajoute le code ci-dessus, j'obtiens maintenant une erreur "AttributeError:" NoneType "object has no attribute" text "".


Vous pouvez également ajouter du code pour vérifier Aucun. Lors du grattage, vous aurez souvent besoin de tout vérifier avant d'essayer d'accéder car vous ne pouvez jamais vraiment être sûr qu'il est là. Vous pouvez faire si len (cols)> 1: col_1 = cols [1] .find ("a") si col_1 n'est pas None: nom_entreprise = col_1.text. Ensuite, vous faites cela pour chaque élément de données et vous obtiendrez simplement des valeurs vides pour les éléments qui n'existent pas, mais vous vous retrouverez avec votre ensemble de données.


Ça a marché! Le seul problème maintenant est que mon code del containers [8] ne saute pas les 7 premiers s, mais c'est assez facile à nettoyer.



0
votes

Certaines lignes du fichier .csv n'ont pas autant de colonnes que prévu. Il semble que vous pensez que le nombre de colonnes devrait être cohérent, il vous suffit donc de vérifier avant de commencer à indexer la ligne comme suit:

for container in containers:
    if len(cols) == 7:
        cols = container.findAll("td")
        company_name = cols[1].find("a").text
        booth_number = cols[2].text
        category = cols[3].text.strip()
        country = cols[5].text

        company_names.append(company_name)
        booth_numbers.append(booth_number)
        categories.append(category)
        countries.append(country)

        csv_out.writerow([company_name, booth_number, category, country])

Je suppose qu'il y aura 7 colonnes car c'est ce que vous avez calculé pour la première ligne, mais vous pouvez changer cela pour ce qu'il devrait être.


1 commentaires

Cela a fonctionné en termes d'élimination de l'erreur, mais le fichier .csv produit est vide.