TypeError: wymagany jest obiekt podobny do bajtów, a nie „str” w Pythonie i CSV

173

TypeError: wymagany jest obiekt podobny do bajtów, a nie „str”

uzyskiwanie powyższego błędu podczas wykonywania poniższego kodu Pythona w celu zapisania danych tabeli HTML w pliku CSV. nie wiem jak uzyskać pomoc rideup.pls.

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)

nad ostatnią linią.

ShivaGuntuku
źródło
cześć - próbowałem uruchomić to na moim ATOM na MX-Linux - ale otrzymuję to: „Śledzenie (ostatnie połączenie): Plik" /home/martin/.atom/python/examples/bs_gumtree_pl.py ", wiersz 20, w <module> writer.writerows (list_of_rows) UnicodeEncodeError: kodek 'ascii' nie może zakodować znaku u '\ xa0' na pozycji 0: numer porządkowy poza zakresem (128) [Zakończono w 2.015s] - zastanawiam się co tu się dzieje! kocham cię usłyszeć
zero

Odpowiedzi:

332

Używasz metodologii Python 2 zamiast Python 3.

Zmiana:

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

Do:

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

a otrzymasz plik z następującym wyjściem:

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

W Pythonie 3 csv pobiera dane wejściowe w trybie tekstowym, podczas gdy w Pythonie 2 pobiera je w trybie binarnym.

Edytowano do dodania

Oto kod, który uruchomiłem:

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
źródło
20
Do użytku z csvmodułem, Python 3 openpowinien mieć również newline=''jako parametr [ref ]
Mark Tolonen
1
Zmień ciąg „wb” na „w”. Wielkie dzięki
Loc Huynh
Jeśli używasz bufora, zobacz odpowiedź Vinylla !
handras
cześć - wypróbowałem kod - i wróciłem: `Traceback (ostatnie wywołanie ostatnio): File" /home/martin/.atom/python/examples/bs_gumtree_pl.py ", wiersz 20, w <module> UnicodeEncodeError : kodek 'ascii' nie może zakodować znaku u '\ xa0' na pozycji 0: numer porządkowy poza zakresem (128) [Zakończono za 1,415 s] `nie mam kleju, co się dzieje
zero
21

Miałem ten sam problem z Pythonem3. Mój kod był w trakcie pisania io.BytesIO().

Zastąpienie io.StringIO()rozwiązanym.

Vinyll
źródło
zdarza mi się również ze stringio
thebeancounter
Jedna uwaga: io.StringIO()to chciwość pamięci i może być bólem głowy przy dużych plikach.
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()

W moim przypadku użyłem BeautifulSoup do napisania .txt w Pythonie 3.x. Miał ten sam problem. Tak jak powiedział @tsduteba, zmień „wb” w pierwszym wierszu na „w”.

Yang Li
źródło
Udzielając odpowiedzi, najlepiej jest wyjaśnić, DLACZEGO twoja odpowiedź jest tą. W takim razie czym ta odpowiedź różni się od zaakceptowanej odpowiedzi?
Stephen Rauch
@StephenRauch Dziękuję za komentarze. Jestem tu nowy i właśnie zacząłem uczyć się Pythona kilka tygodni temu. Postaram się udzielić lepszej odpowiedzi w przyszłości.
Yang Li
Możesz edytować ten post i dodawać więcej szczegółów. Kliknij przycisk edycji poniżej i po lewej stronie posta.
Stephen Rauch
@StephenRauch Dzięki za wskazówki!
Yang Li
1

po prostu zmień wb na w

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

do

outfile=open('./immates.csv','w')
Sarath Ak
źródło
1

Otwierasz plik csv w trybie binarnym, powinno być '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
źródło