UnicodeEncodeError: codec 'charmap' không thể mã hóa các ký tự


205

Tôi đang cố gắng để cạo một trang web, nhưng nó gây ra lỗi cho tôi.

Tôi đang sử dụng mã sau đây:

import urllib.request
from bs4 import BeautifulSoup

get = urllib.request.urlopen("https://www.website.com/")
html = get.read()

soup = BeautifulSoup(html)

print(soup)

Và tôi đang nhận được lỗi sau:

File "C:\Python34\lib\encodings\cp1252.py", line 19, in encode
    return codecs.charmap_encode(input,self.errors,encoding_table)[0]
UnicodeEncodeError: 'charmap' codec can't encode characters in position 70924-70950: character maps to <undefined>

Tôi có thể làm gì để sữa nó?

Câu trả lời:


258

Tôi đã nhận được điều tương tự UnicodeEncodeErrorkhi lưu nội dung web bị loại vào một tệp. Để sửa nó, tôi đã thay thế mã này:

with open(fname, "w") as f:
    f.write(html)

Với cái này:

import io
with io.open(fname, "w", encoding="utf-8") as f:
    f.write(html)

Việc sử dụng iomang lại cho bạn khả năng tương thích ngược với Python 2.

Nếu bạn chỉ cần hỗ trợ Python 3, bạn có thể sử dụng openhàm dựng sẵn thay thế:

with open(fname, "w", encoding="utf-8") as f:
    f.write(html)

6
Trong mac (python 3) hoạt động hoàn hảo với chỉ mở mà không cần mã hóa, nhưng trong windows (w10, python3) không phải là một tùy chọn. Chỉ hoạt động theo cách đó, với mã hóa = "utf-8" param.
xtornasol512

3
Cảm ơn bạn. Nó hoạt động với tôi, tôi đã làm việc với các tệp xml và viết kết quả của xml.toprettyxml () trong một tệp mới
Luis Cabrera Benito

1
Đây phải là câu trả lời được chấp nhận vì cuối cùng nó sẽ ghi một chuỗi vào đầu ra, và không phải là biểu diễn chuỗi của byte.
Shirkan

OP yêu cầu đọc tệp tuy nhiên, không ghi tệp. Vấn đề dường như có liên quan đến giao diện điều khiển.
NaturalBornCamper

187

Tôi đã sửa nó bằng cách thêm .encode("utf-8")vào soup.

Điều đó có nghĩa là print(soup)trở thành print(soup.encode("utf-8")).


3
không mã hóa mã hóa ký tự của môi trường của bạn (ví dụ: bảng điều khiển) bên trong tập lệnh của bạn, thay vào đó
jfs

Đây chỉ là in repr của một bytesđối tượng, nó sẽ in dưới dạng một \xchuỗi các chuỗi nếu có nhiều văn bản được mã hóa UTF-8. Tôi khuyên bạn nên sử dụng win_unicode_console, như @JFSebastian gợi ý.
Eryk CN

2
Tôi đã sử dụng giải pháp trên nhưng sẽ gặp sự cố: class MyStreamListener (tweepy.StreamListener): def on_status (self, status): print (str (status.encode ("utf-8"))) UnicodeEncodeError: 'charmap' codec có thể ' t mã hóa ký tự '\ u2019' ở vị trí 87: ánh xạ ký tự thành <không xác định>
Vivek

2
Điều này làm cho nó in ra b'\x02x\xc2\xa9'(một đối tượng byte) thay vào đó
MilkyWay90

1
print(soup.encode("utf-8"))làm việc cho tôi, nhưng trước đó tôi cũng phải thêmwith open("f_name", encoding="utf-8") as f: soup = BeautifulSoup(f, "html.parser")
TheWalkingData

44

Trong Python 3.7 và chạy Windows 10, điều này đã hoạt động (Tôi không chắc liệu nó có hoạt động trên các nền tảng khác và / hoặc các phiên bản khác của Python không)

Thay thế dòng này:

with open('filename', 'w') as f:

Với cái này:

with open('filename', 'w', encoding='utf-8') as f:

Lý do tại sao nó hoạt động là do mã hóa được thay đổi thành UTF-8 khi sử dụng tệp, do đó, các ký tự trong UTF-8 có thể được chuyển đổi thành văn bản, thay vì trả về lỗi khi gặp ký tự UTF-8 không suppord bởi mã hóa hiện tại.


1
in (súp) return \ xd0 \ xbf \ xd0 \ xbe \ xd0 \ xb6 \ xd0 \ xb0 \ xd0 \ xbb \ xd1 \ X83 \ xd0 \ xb9 \ xd
Cà phê Intime

12

Trong khi lưu phản hồi của yêu cầu get, lỗi tương tự đã được ném vào Python 3.7 trên cửa sổ 10. Phản hồi nhận được từ URL, mã hóa là UTF-8 vì vậy luôn luôn nên kiểm tra mã hóa để có thể vượt qua để tránh sự cố nhỏ như vậy vì nó thực sự giết rất nhiều thời gian trong sản xuất

import requests
resp = requests.get('https://en.wikipedia.org/wiki/NIFTY_50')
print(resp.encoding)
with open ('NiftyList.txt', 'w') as f:
    f.write(resp.text)

Khi tôi thêm mã hóa = "utf-8" bằng lệnh mở, nó đã lưu tệp với phản hồi chính xác

with open ('NiftyList.txt', 'w', encoding="utf-8") as f:
    f.write(resp.text)

10

Ngay cả tôi cũng gặp vấn đề tương tự với mã hóa xảy ra khi bạn cố in nó, đọc / ghi hoặc mở nó. Như những người khác đã đề cập ở trên, việc thêm .encoding = "utf-8" sẽ giúp ích nếu bạn đang cố in nó.

súp.encode ("utf-8")

Nếu bạn đang cố mở dữ liệu bị loại bỏ và có thể ghi nó vào một tệp, thì hãy mở tệp bằng (......, mã hóa = "utf-8")

với open (filename_csv, 'w', newline = '', mã hóa = "utf-8") là csv_file:


6

Đối với những người vẫn nhận được lỗi này, thêm encode("utf-8")vào soupcũng sẽ sửa lỗi này.

soup = BeautifulSoup(html_doc, 'html.parser').encode("utf-8")
print(soup)

2
soupkhông còn là BeautifulSoupđối tượng sau khi bạn làm điều này vì vậy nó không thể bị thao túng hoặc tìm kiếm
NaturalBornCamper
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.