UnicodeEncodeError:“charmap”编解码器无法在位置 1087 编码字符“\u011f”:字符映射到 <undefined>
Posted
技术标签:
【中文标题】UnicodeEncodeError:“charmap”编解码器无法在位置 1087 编码字符“\\u011f”:字符映射到 <undefined>【英文标题】:UnicodeEncodeError: 'charmap' codec can't encode character '\u011f' in position 1087: character maps to <undefined>UnicodeEncodeError:“charmap”编解码器无法在位置 1087 编码字符“\u011f”:字符映射到 <undefined> 【发布时间】:2021-01-27 21:09:06 【问题描述】:我的抓取功能有问题。
在这个项目中,我有一个 sqlite3 数据库,其中包含指向音乐专辑评论的链接。我创建了一个包含这两种方法的 scraper.py 文件:
from bs4 import BeautifulSoup
import requests
def take_source(url):
if 'http://' or 'https://' in url:
source = requests.get(url).text
return source
else:
print("Invalid URL")
def extract_corpus(source):
soup = BeautifulSoup(source, "html.parser")
soup.prettify().encode('cp1252', errors='ignore')
corpus = []
for e in soup.select("p"):
corpus.append(e.text)
return corpus
我在一个名为 embedding.py 的文件中调用 extract_corpus 方法, 在这个文件中,我创建了一个与 sqlite3 数据库的连接,并将数据放入 Pandas 数据框中。 我想将所有链接的内容存储在 csv 文件中。我的 embedding.py 文件包含:
import sqlite3
import pandas as pd
import scraper
import csv
#create connection with sqlite db
con = sqlite3.connect("database.sqlite")
#creating a pandas data frame
query = pd.read_sql_query("SELECT url, artist, title FROM reviews;", con)
#populating data frame with urls
df = pd.DataFrame(query, columns=['url', 'artist', 'title'])
#preparing the .csv file for storing the reviews
with open('reviews.csv', 'w') as csvfile:
fieldnames = ['title', 'artist', 'review']
writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
writer.writeheader()
def append_csv(tit,art,rev):
with open('reviews.csv','a') as csv_f:
writer = csv.DictWriter(csv_f, fieldnames=fieldnames)
writer.writerow('title': tit, 'artist':art,'review':rev)
for i, row in df.iterrows():
album = (str(row.__getitem__('title')))
artist = (str(row.__getitem__('artist')))
review = str(scraper.extract_corpus(scraper.take_source(str(row.__getitem__('url')))))
append_csv(album,artist,review)
当我运行这个文件时,它适用于初始的一组链接,然后它会中断返回标题中的错误。这是错误:
Traceback(最近一次调用最后一次):文件 “C:/Users/kikko/PycharmProjects/SongsBot/embedding.py”,第 59 行,在 append_csv(album,artist,review) 文件“C:/Users/kikko/PycharmProjects/SongsBot/embedding.py”,第 52 行,在 append_csv writer.writerow('title': tit, 'artist':art,'review':rev) File "C:\Users\kikko\AppData\Local\Programs\Python\Python37-32\lib\csv.py ", 第 155 行,在 writerow 中 返回 self.writer.writerow(self._dict_to_list(rowdict)) 文件 "C:\Users\kikko\AppData\Local\Programs\Python\Python37-32\lib\encodings\cp1252.py", 第 19 行,在编码中 return codecs.charmap_encode(input,self.errors,encoding_table)[0] UnicodeEncodeError: 'charmap' codec can't encode character '\u011f' in 位置 1087:字符映射到
很遗憾,我找不到错误。
【问题讨论】:
用您自己的话说,您希望soup.prettify().encode('cp1252', errors='ignore')
做什么?特别是,您是否希望修改原始的soup
?它没有:它改为创建字符串的字节编码,然后将其丢弃,未使用。
【参考方案1】:
看来你这里有多重误解。
soup.prettify().encode('cp1252', errors='ignore')
这没有任何用处:您创建一个表示 HTML 源的字符串(使用.prettify
),将其编码为字节(.encode
),然后对生成的对象不做任何事情。 soup
未修改。
幸运的是,在此过程中,您不需要或不想对编码做任何事情。但最好完全删除这条线,以免误导自己。
for e in soup.select("p"):
corpus.append(e.text)
return corpus
您将生成并返回一个字符串列表,稍后您将尝试使用str
将其强制转换为字符串。结果将显示列表的表示形式:即,它将包含在[]
中,并用逗号分隔每个字符串的项目、引号和转义序列。这可能不是您想要的。
我假设您想将字符串连接在一起,例如'\n'.join(corpus)
。但是,像这样的多行数据不适合存储在 CSV 中。 (转义列表表示形式存储在 CSV 中也相当尴尬。您可能应该更多地考虑如何格式化数据。)
review = str(scraper.extract_corpus(scraper.take_source(str(row.__getitem__('url')))))
首先,你不应该直接调用像__getitem__
这样的双下划线方法。我知道它们在文档中是这样写的;这只是 Python 一般如何工作的产物。您应该使用__getitem__
,因此:row['url']
。
您应该期望结果已经是一个字符串,所以内部的str
调用是无用的。然后你用take_source
,有这个错误:
if 'http://' or 'https://' in url:
这个does not do what you want;该函数将始终认为 URL 是“有效的”。
无论如何,一旦你设法 extract_corpus
并从中强行生成一个字符串,你所询问的实际问题就会发生:
with open('reviews.csv','a') as csv_f:
您不能简单地将任意字符串写入 cp1252 编码的文件(您知道这是正在使用的字符串,因为在您的堆栈跟踪中提到了cp1252.py
;它是您平台的默认设置)。 这个是你应该指定文件编码的地方。例如,您可以指定应该使用encoding='utf-8'
写入文件,它可以处理任何字符串。 (当您出于任何其他目的再次打开文件时,您还需要明确指定这一点。)
如果您坚持手动进行编码,那么您将需要 .encode
对文件进行 .write
ing 处理。但是,因为.encode
产生原始编码字节,所以您需要以二进制模式打开文件(如'ab'
),这也意味着您必须自己处理通用换行编码。这不是一个愉快的任务。请按照设计使用的方式使用该库。
在正确处理文本编码等方面,您不能仅通过尝试修复出现的每个错误来编写质量不错的正确代码,执行网络搜索每个错误或通过强制转换消除类型错误。您必须真正了解发生了什么。我不能强调这一点。请开始here,然后也阅读here。从上到下阅读,旨在理解所说的内容,而不是试图解决任何具体问题。
【讨论】:
非常感谢您详细而一致的回复。感谢您的澄清,我已经成功解决了我遇到的问题。不幸的是,我对这些概念不太熟悉,我写了一些代码而没有注意这些问题。仔细看了你传给我的文章,我可以说我的思路清晰多了。再次感谢您给我的时间。以上是关于UnicodeEncodeError:“charmap”编解码器无法在位置 1087 编码字符“\u011f”:字符映射到 <undefined>的主要内容,如果未能解决你的问题,请参考以下文章