TypeError: un objet de type octets est requis, pas 'str' en python et CSV


173

TypeError: un objet de type octets est requis, pas 'str'

obtenir l'erreur ci-dessus lors de l'exécution du code python ci-dessous pour enregistrer les données de la table HTML dans le fichier Csv. ne sais pas comment se débarrasser de rideup.pls aidez-moi.

import csv
import requests
from bs4 import BeautifulSoup

url='http://www.mapsofindia.com/districts-india/'
response=requests.get(url)
html=response.content

soup=BeautifulSoup(html,'html.parser')
table=soup.find('table', attrs={'class':'tableizer-table'})
list_of_rows=[]
for row in table.findAll('tr')[1:]:
    list_of_cells=[]
    for cell in row.findAll('td'):
        list_of_cells.append(cell.text)
    list_of_rows.append(list_of_cells)
outfile=open('./immates.csv','wb')
writer=csv.writer(outfile)
writer.writerow(["SNo", "States", "Dist", "Population"])
writer.writerows(list_of_rows)

au-dessus de la dernière ligne.



bonjour - j'ai essayé d'exécuter ceci sur mon ATOM sur MX-Linux - mais je récupère ceci: ´Traceback (dernier appel le plus récent): Fichier "/home/martin/.atom/python/examples/bs_gumtree_pl.py", ligne 20, dans <module> writer.writerows (list_of_rows) UnicodeEncodeError: le codec 'ascii' ne peut pas encoder le caractère u '\ xa0' en position 0: l'ordinal n'est pas dans la plage (128) [Terminé en 2.015s] ´ eh bien je me demande quoi continue ici!? J'adore avoir de vos nouvelles
zéro

Réponses:


332

Vous utilisez la méthodologie Python 2 au lieu de Python 3.

Changement:

outfile=open('./immates.csv','wb')

À:

outfile=open('./immates.csv','w')

et vous obtiendrez un fichier avec la sortie suivante:

SNo,States,Dist,Population
1,Andhra Pradesh,13,49378776
2,Arunachal Pradesh,16,1382611
3,Assam,27,31169272
4,Bihar,38,103804637
5,Chhattisgarh,19,25540196
6,Goa,2,1457723
7,Gujarat,26,60383628
.....

En Python 3, csv prend l'entrée en mode texte, alors qu'en Python 2, il l'a prise en mode binaire.

Modifié pour ajouter

Voici le code que j'ai exécuté:

url='http://www.mapsofindia.com/districts-india/'
html = urllib.request.urlopen(url).read()
soup = BeautifulSoup(html)
table=soup.find('table', attrs={'class':'tableizer-table'})
list_of_rows=[]
for row in table.findAll('tr')[1:]:
    list_of_cells=[]
    for cell in row.findAll('td'):
        list_of_cells.append(cell.text)
    list_of_rows.append(list_of_cells)
outfile = open('./immates.csv','w')
writer=csv.writer(outfile)
writer.writerow(['SNo', 'States', 'Dist', 'Population'])
writer.writerows(list_of_rows)

20
Pour une utilisation avec le csvmodule, le Python 3 opendevrait également avoir newline=''comme paramètre [ref ]
Mark Tolonen

1
Changer la chaîne «wb» en «w» fonctionne pour moi. Merci beaucoup
Loc Huynh

Si vous utilisez un tampon, voyez la réponse de vinyll !
handras

salut - j'ai essayé le code - et j'ai récupéré ceci: `Traceback (dernier appel le plus récent): Fichier" /home/martin/.atom/python/examples/bs_gumtree_pl.py ", ligne 20, dans <module> UnicodeEncodeError : le codec 'ascii' ne peut pas encoder le caractère u '\ xa0' en position 0: ordinal pas dans la plage (128) [Terminé en 1,415s] `Je n'ai pas de colle ce qui se passe ici
zéro

21

J'ai eu le même problème avec Python3. Mon code écrivait dans io.BytesIO().

Remplacement par io.StringIO()résolu.


m'arrive aussi avec stringio
thebeancounter

Une considération: io.StringIO()c'est la cupidité de la mémoire et peut être un casse-tête avec des fichiers volumineux.
Flavio

1
file = open('parsed_data.txt', 'w')
for link in soup.findAll('a', attrs={'href': re.compile("^http")}): print (link)
soup_link = str(link)
print (soup_link)
file.write(soup_link)
file.flush()
file.close()

Dans mon cas, j'ai utilisé BeautifulSoup pour écrire un .txt avec Python 3.x. C'était le même problème. Tout comme @tsduteba l'a dit, changez le «wb» de la première ligne en «w».


Lorsque vous donnez une réponse, il est préférable d' expliquer pourquoi votre réponse est la bonne. Dans ce cas, en quoi cette réponse diffère-t-elle de la réponse acceptée?
Stephen Rauch

@StephenRauch Merci pour vos commentaires. Je suis nouveau ici et je viens de commencer à apprendre Python il y a plusieurs semaines. J'essaierai de donner une meilleure réponse à l'avenir.
Yang Li

Vous pouvez modifier ce message et ajouter plus de détails. Appuyez sur le bouton Modifier ci-dessous et à gauche du message.
Stephen Rauch

@StephenRauch Merci pour vos conseils!
Yang Li

1

il suffit de changer wb en w

outfile=open('./immates.csv','wb')

à

outfile=open('./immates.csv','w')

1

Vous ouvrez le fichier csv en mode binaire, il devrait être 'w'

import csv

# open csv file in write mode with utf-8 encoding
with open('output.csv','w',encoding='utf-8',newline='')as w:
    fieldnames = ["SNo", "States", "Dist", "Population"]
    writer = csv.DictWriter(w, fieldnames=fieldnames)
    # write list of dicts
    writer.writerows(list_of_dicts) #writerow(dict) if write one row at time
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.