TypeError: bắt buộc phải có một đối tượng giống byte, không phải là 'str' trong python và CSV


173

TypeError: bắt buộc phải có một đối tượng giống byte, không phải là 'str'

gặp lỗi trên trong khi Thực hiện bên dưới mã python để lưu dữ liệu bảng HTML trong tệp Csv. không biết làm thế nào để có được Rideup. Xin hãy giúp tôi.

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)

ở trên dòng cuối cùng.



xin chào - tôi đã thử chạy cái này trên ATOM của tôi trên MX-Linux - nhưng tôi đã nhận lại cái này: Tracrac (cuộc gọi gần đây nhất): Tệp "/home/martin/.atom/python/examples/bs_gumtree_pl.py", dòng 20, trong <module> wr.writerows (list_of_rows) UnicodeEncodeError: 'ascii' codec không thể mã hóa ký tự u '\ xa0' ở vị trí 0: thứ tự không nằm trong phạm vi (128) [Hoàn thành trong 2.015s] tôi cũng tự hỏi điều gì đi về đây!? thích nghe từ bạn
số không

Câu trả lời:


331

Bạn đang sử dụng phương pháp luận Python 2 thay vì Python 3.

Thay đổi:

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

Đến:

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

và bạn sẽ nhận được một tập tin với đầu ra sau:

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

Trong Python 3 csv lấy đầu vào ở chế độ văn bản, trong khi ở Python 2, nó lấy nó ở chế độ nhị phân.

Đã chỉnh sửa để thêm

Đây là mã tôi đã chạy:

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
Để sử dụng với csvmô-đun, Python 3 opencũng phải có newline=''tham số [ref ]
Mark Tolonen

1
Thay đổi chuỗi 'wb' thành 'w' hoạt động với tôi. Cảm ơn rất nhiều
Loc Huynh

Nếu bạn đang sử dụng bộ đệm, hãy xem câu trả lời của vinyll !
handras

xin chào - tôi đã thử mã - và đã nhận lại mã này: `TracBack (cuộc gọi gần đây nhất) : 'ascii' codec không thể mã hóa ký tự u '\ xa0' ở vị trí 0: thứ tự không nằm trong phạm vi (128) [Hoàn thành trong 1.415s] `tôi không có keo nào xảy ra ở đây
zero

21

Tôi đã có cùng một vấn đề với Python3. Mã của tôi đã được viết vào io.BytesIO().

Thay thế bằng io.StringIO()giải quyết.


xảy ra với tôi với StringIO cũng
thebeancounter

Một xem xét: io.StringIO()là tham lam bộ nhớ và có thể là một vấn đề đau đầu với các tập tin lớn.
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()

Trong trường hợp của tôi, tôi đã sử dụng BeautifulSoup để viết .txt bằng Python 3.x. Nó có cùng một vấn đề. Như @tsduteba đã nói, hãy thay đổi 'wb' trong dòng đầu tiên thành 'w'.


Khi đưa ra câu trả lời, tốt nhất là đưa ra một số lời giải thích về lý do TẠI SAO câu trả lời của bạncâu trả lời . Trong trường hợp này, câu trả lời này khác với câu trả lời được chấp nhận như thế nào?
Stephen Rauch

@StephenRauch Cảm ơn bạn đã bình luận. Tôi mới ở đây và mới bắt đầu học Python vài tuần trước. Tôi sẽ cố gắng đưa ra câu trả lời tốt hơn trong tương lai.
Yang Li

Bạn có thể chỉnh sửa bài đăng này, và thêm chi tiết. Nhấn nút chỉnh sửa bên dưới và bên trái của bài viết.
Stephen Rauch

@StephenRauch Cảm ơn lời khuyên của bạn!
Yang Li

1

chỉ cần thay đổi wb thành w

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

đến

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

1

Bạn đang mở tệp csv ở chế độ nhị phân, nó sẽ là '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
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.