Python新手求助:如何在BeautifulSoup解析前后移除非BMP字符?
解决BeautifulSoup爬取时非BMP字符(表情符号)导致程序崩溃的问题
嘿,我之前也碰到过一模一样的问题!那些表情符号这类非BMP字符(超出Unicode基本多语言平面的字符)经常会在爬取时搞崩程序,尤其是在处理文本输出或者写入文件的时候。给你几个实用的解决思路,按需求选就行:
方法1:获取网页内容时直接过滤非BMP字符
在把内容传给BeautifulSoup之前,先把所有非BMP字符清理掉,用正则表达式就能轻松做到:
import re import requests from bs4 import BeautifulSoup target_url = "你的目标网页URL" response = requests.get(target_url) # 移除所有U+10000到U+10FFFF范围内的非BMP字符 clean_html = re.sub(r'[\U00010000-\U0010ffff]', '', response.text) # 用清理后的HTML创建BeautifulSoup对象 soup = BeautifulSoup(clean_html, 'html.parser') # 接下来正常解析提取数据即可
方法2:通过编码解码忽略非BMP字符
利用Python字符串的编码解码机制,直接忽略无法用UTF-8编码的非BMP字符:
import requests from bs4 import BeautifulSoup target_url = "你的目标网页URL" response = requests.get(target_url) # 先编码为UTF-8并忽略非法字符,再解码回字符串 clean_html = response.text.encode('utf-8', 'ignore').decode('utf-8') soup = BeautifulSoup(clean_html, 'html.parser')
方法3:解析后处理单条文本内容
如果不想整个HTML都过滤,只想在提取具体文本时处理,可以写一个小工具函数:
import requests from bs4 import BeautifulSoup def strip_non_bmp(text): # 只保留Unicode基本平面内的字符 return ''.join(char for char in text if char <= '\uFFFF') target_url = "你的目标网页URL" response = requests.get(target_url) soup = BeautifulSoup(response.text, 'html.parser') # 提取文本时调用工具函数清理 for paragraph in soup.find_all('p'): clean_text = strip_non_bmp(paragraph.get_text()) print(clean_text) # 或者写入文件等后续操作
额外提醒
如果你的问题是出在写入文件时编码报错,其实也可以不用移除这些字符,只要打开文件时指定用UTF-8编码即可:
with open('output.txt', 'w', encoding='utf-8') as f: f.write(clean_text)
这样即使保留表情符号也能正常保存,看你需求选择就好~
内容的提问来源于stack exchange,提问作者akisonlyforu




