TypeError: Ein byteähnliches Objekt ist erforderlich, nicht 'str' in Python und CSV


173

TypeError: Ein byteähnliches Objekt ist erforderlich, nicht 'str'

Fehler beim Ausführen des folgenden Python-Codes zum Speichern der HTML-Tabellendaten in der CSV-Datei. Ich weiß nicht, wie ich Rideup bekommen soll. Bitte helfen Sie mir.

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)

auf über der letzten Zeile.



Hallo - ich habe versucht, dies auf meinem ATOM unter MX-Linux auszuführen - aber ich bekomme Folgendes zurück: ´Traceback (letzter Aufruf zuletzt): Datei "/home/martin/.atom/python/examples/bs_gumtree_pl.py", Zeile 20, in <module> writer.writerows (list_of_rows) UnicodeEncodeError: 'ascii'-Codec kann das Zeichen u' \ xa0 'in Position 0 nicht codieren: Ordnungszahl nicht im Bereich (128) [Fertig in 2.015s] ´ Nun, ich frage mich, was geht hier weiter !? liebe es von dir zu hören
— null

Antworten:


330

Sie verwenden die Python 2-Methode anstelle von Python 3.

Veränderung:

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

Zu:

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

und Sie erhalten eine Datei mit der folgenden Ausgabe:

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
.....

In Python 3 übernimmt csv die Eingabe im Textmodus, während sie in Python 2 im Binärmodus erfolgt.

Bearbeitet, um hinzuzufügen

Hier ist der Code, den ich ausgeführt habe:

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)

19
Für die Verwendung mit dem csvModul sollte Python 3 openauch newline=''als Parameter [ref ]
— Mark Tolonen

1
Ändern Sie die Zeichenfolge 'wb' in 'w', was für mich funktioniert. Vielen Dank
— Loc Huynh

Wenn Sie einen Puffer verwenden, lesen Sie die Antwort von vinyll !
— Handras

Hallo, ich habe den Code ausprobiert und Folgendes zurückbekommen: `Traceback (letzter Aufruf zuletzt): Datei" /home/martin/.atom/python/examples/bs_gumtree_pl.py ", Zeile 20, in <module> UnicodeEncodeError : 'ascii' Codec kann das Zeichen u '\ xa0' in Position 0 nicht codieren: Ordnungszahl nicht im Bereich (128) [Fertig in 1.415s] `Ich habe keinen Kleber, was hier vor sich geht
— Null

21

Ich hatte das gleiche Problem mit Python3. Mein Code schrieb in io.BytesIO().

Ersetzen durch io.StringIO()gelöst.


passiert mir auch mit stringio
— thebeancounter

Eine Überlegung: io.StringIO()ist Speichergier und kann bei großen Dateien Kopfschmerzen verursachen.
— 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()

In meinem Fall habe ich BeautifulSoup verwendet, um mit Python 3.x eine TXT-Datei zu schreiben. Es hatte das gleiche Problem. Ändern Sie, wie @tsduteba sagte, das 'wb' in der ersten Zeile in 'w'.


Wenn Sie eine Antwort geben, ist es vorzuziehen, eine Erklärung zu geben , WARUM Ihre Antwort diejenige ist. Wie unterscheidet sich diese Antwort in diesem Fall von der akzeptierten Antwort?
— Stephen Rauch

@ StephenRauch Vielen Dank für Ihre Kommentare. Ich bin neu hier und habe vor einigen Wochen angefangen, Python zu lernen. Ich werde versuchen, in Zukunft eine bessere Antwort zu geben.
— Yang Li

Sie können diesen Beitrag bearbeiten und weitere Details hinzufügen. Klicken Sie auf die Schaltfläche Bearbeiten unten und links neben dem Beitrag.
— Stephen Rauch

@ StephenRauch Danke für deine Tipps!
— Yang Li

1

ändere einfach wb in w

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

zu

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

1

Sie öffnen die CSV-Datei im Binärmodus, sollte es sein '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
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.