背景
スクレイピングしたデータをBQにアップロードする。
そのために改行区切りのJSONを作る。
その際、余計な文字が混入していることでエラーが発生した。
エラー内容
対象の文字列
...\udb40\udd00\u539f...
エラー内容
UnicodeEncodeError: 'utf-8' codec can't encode characters in position 40-41: surrogates not allowed
なんぞこれ?
\udb40
や\udd00
は異体字セレクタという微妙な字形を区別するための文字コードだった。
surrogates not allowed
とのことなのでこれらを無くせば良いっぽい。
削除すべき文字コードを一覧化した
https://sheilart.github.io/Azure-Alphant/surrogates.html
これ使えそうだから一覧化してみよう..2048件..なんか多いな
const elms = Array.from(document.querySelectorAll('article'));
elms.map((elm)=>{
return elm.querySelector('p:nth-child(6)').textContent;
})
例外的な事象ぽいし、ここまでいらないや。一旦その場しのぎでこの人の判別してるやつをパクろう
IVSのセレクタ文字判別用のクラスを作ってみた
\uDB40
\uDD00
\uDDEF
\uFE00
\uFE0F
\u180B
\u180d
文字コードを削除した
このメソッドで削除後のテキストを得る
import re
def remove_surrogates(text: str):
return re.sub('\udb40|\udd00|\uddef|\ufe00|\ufe0f|\u180b|\u180d', '', text)
備考:代替策
その後メンテナンスが面倒そうだったので ↓ で対応した。
def to_unicode(text:str):
return unicodedata.normalize("NFKC", text)
参考
文字って何かね?>異体字セレクタ(IVS)
異体字セレクタってなあに
Unicodeエスケープシーケンスを変換したい
surrogates
charbase
IVSのセレクタ文字判別用のクラスを作ってみた
Unicodeエスケープシーケンス変換ツール