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.

ShivaGuntuku
la source
Double
tripleee
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)
dstudeba
la source
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.

vinyll
la source
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».

Yang Li
la source
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')
Sarath Ak
la source
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
Sohan Das
la source