Python 3.x 替换Unicode字符系列/Python/Twitter

Python 3.x 替换Unicode字符系列/Python/Twitter,python-3.x,twitter,unicode,python-unicode,Python 3.x,Twitter,Unicode,Python Unicode,我使用twitterapi和python3.3从tweet中提取文本,我遇到了tweet的一部分,tweet在其中添加了三个符号。它们如下所示。 这两个标志和竖起的大拇指似乎是导致问题的原因。以下是纯文本推文 RT @John_Hunt07: Just voted for @marcorubio is Florida! I am ready for a New American Century!! #FLPrimary \ud83c\uddfa\ud83c\uddf8\ud83c\uddfa\

我使用twitterapi和python3.3从tweet中提取文本,我遇到了tweet的一部分,tweet在其中添加了三个符号。它们如下所示。

这两个标志和竖起的大拇指似乎是导致问题的原因。以下是纯文本推文

RT @John_Hunt07: Just voted for @marcorubio is Florida! I am ready for a New American Century!! #FLPrimary \ud83c\uddfa\ud83c\uddf8\ud83c\uddfa\ud83c\uddf8\ud83d\udc4d
下面是我正在使用的代码

import json
import mysql.connector
import sys
from datetime import datetime
from MySQLCL import MySQLCL

class Functions(object):
"""This is a class for Python functions"""

@staticmethod
def Clean(string):
    temp = str(string)
    temp = temp.replace("'", "").replace("(", "").replace(")", "").replace(",", "").strip()
    return temp

@staticmethod
def ParseTweet(string):
    for x in range(0, len(string)):
        tweetid = string[x]["id_str"]
        tweetcreated = string[x]["created_at"]
        tweettext = string[x]["text"]
        tweetsource = string[x]["source"]
        tweetsource = tweetsource
        truncated = string[x]["truncated"]
        inreplytostatusid = string[x]["in_reply_to_status_id"]
        inreplytouserid = string[x]["in_reply_to_user_id"]
        inreplytoscreenname = string[x]["in_reply_to_screen_name"]
        geo = string[x]["geo"]
        coordinates = string[x]["coordinates"]
        place = string[x]["place"]
        contributors = string[x]["contributors"]
        isquotestatus = string[x]["is_quote_status"]
        retweetcount = string[x]["retweet_count"]
        favoritecount = string[x]["favorite_count"]
        favorited = string[x]["favorited"]
        retweeted = string[x]["retweeted"]
        if "possibly_sensitive" in string[x]:
            possiblysensitive = string[x]["possibly_sensitive"]
        else:
            possiblysensitive = ""
        language = string[x]["lang"]

        #print(possiblysensitive)
        print(Functions.UnicodeFilter(tweettext))
        #print(inreplytouserid)
        #print("INSERT INTO tweet(ExTweetID, TweetText, Truncated, InReplyToStatusID, InReplyToUserID, InReplyToScreenName, IsQuoteStatus, RetweetCount, FavoriteCount, Favorited, Retweeted, Language, TweetDate, TweetSource, PossiblySensitive) VALUES (" + str(tweetid) + ", '" + Functions.UnicodeFilter(tweettext) + "', " + str(truncated) + ", " + Functions.CheckNull(inreplytostatusid) + ", " + Functions.CheckNull(inreplytouserid) + ", '" + Functions.CheckNull(inreplytoscreenname) + "', " + str(isquotestatus) + ", " + str(retweetcount) + ", " + str(favoritecount) + ", " + str(favorited) + ", " + str(retweeted) + ", '" + str(language) + "', '" + Functions.ToSQL(tweetcreated) + "', '" + Functions.ToSQL(tweetsource) + "', " + str(possiblysensitive) + ")")
        #MySQLCL.Set("INSERT INTO tweet(ExTweetID, TweetText, Truncated, InReplyToStatusID, InReplyToUserID, InReplyToScreenName, IsQuoteStatus, RetweetCount, FavoriteCount, Favorited, Retweeted, Language, TweetDate, TweetSource, PossiblySensitive) VALUES (" + str(tweetid) + ", '" + tweettext + "', " + str(truncated) + ", " + Functions.CheckNullNum(inreplytostatusid) + ", " + Functions.CheckNullNum(inreplytouserid) + ", '" + Functions.CheckNull(inreplytoscreenname) + "', " + str(isquotestatus) + ", " + str(retweetcount) + ", " + str(favoritecount) + ", " + str(favorited) + ", " + str(retweeted) + ", '" + language + "', '" + str(Functions.FormatDate(tweetcreated)) + "', '" + str(Functions.UnicodeFilter(tweetsource)) + "', " + str(possiblysensitive) + ")")

@staticmethod
def ToBool(variable):
    if variable.lower() == 'true':
        return True
    elif variable.lower() == 'false':
        return False

@staticmethod
def CheckNullNum(var):
    if var == None:
        return "0"
    else:
        return str(var)

@staticmethod
def CheckNull(var):
    if var == None:
        return ""
    else:
        return var

@staticmethod
def ToSQL(var):
    temp = var
    temp = temp.replace("'", "")
    return str(temp)

@staticmethod
def UnicodeFilter(var):
    temp = var
    temp = temp.replace(chr(0x2019), "")
    temp = temp.replace(chr(0x003c), "(lessthan)")
    temp = temp.replace(chr(0x003e), "(greaterthan)")
    temp = temp.replace(chr(0xd83c), "")
    temp = temp.replace(chr(0xddfa), "")
    temp = temp.replace(chr(0xddf8), "")
    temp = temp.replace(chr(0xd83d), "")
    temp = temp.replace(chr(0xdc4d), "")
    temp = Functions.ToSQL(temp)
    return temp

@staticmethod
def FormatDate(var):
    temp = var
    dt = datetime.strptime(temp, "%a %b %d %H:%M:%S %z %Y")
    retdt = str(dt.year) + "-" + str(dt.month) + "-" + str(dt.day) + "T" + str(dt.hour) + ":" + str(dt.minute) + ":" + str(dt.second)
    return retdt
如您所见,我一直在使用UnicodeDefilter函数来尝试过滤掉十六进制中的unicode字符。该函数在处理单个unicode字符时起作用,但当遇到多个放置在一起的unicode字符时,此方法失败并出现以下错误:

“charmap”编解码器无法对位置107-111中的字符进行编码:字符映射为“未定义”

你们当中有人对如何克服这个问题有什么想法吗

更新:我已经尝试了解决方案,但仍然遇到同样的问题。但是,我决定看看是否有任何特定的字符导致了问题,所以我决定逐个字符地将字符打印到控制台。这给了我如下错误:

“charmap”编解码器无法对位置0中的字符“\u0001fA”进行编码:字符映射为“未定义”

看到这一点后,我将其添加到UnicodeFilter函数并继续测试。我在一个字符一个字符地打印推文时遇到了多个相同类型的错误。然而,我不想继续做出这些例外。例如,请参见修改后的过滤器功能:

@staticmethod
def UnicodeFilter(var):
    temp = var
    temp = temp.encode(errors='ignore').decode('utf-8')
    temp = temp.replace(chr(0x2019), "")
    temp = temp.replace(chr(0x003c), "(lessthan)")
    temp = temp.replace(chr(0x003e), "(greaterthan)")
    temp = temp.replace(chr(0xd83c), "")
    temp = temp.replace(chr(0xddfa), "")
    temp = temp.replace(chr(0xddf8), "")
    temp = temp.replace(chr(0xd83d), "")
    temp = temp.replace(chr(0xdc4d), "")
    temp = temp.replace(chr(0x2026), "")
    temp = temp.replace(u"\U0001F1FA", "")
    temp = temp.replace(u"\U0001F1F8", "")
    temp = temp.replace(u"\U0001F44D", "")
    temp = temp.replace(u"\U00014F18", "")
    temp = temp.replace(u"\U0001F418", "")
    temp = temp.replace(u"\U0001F918", "")
    temp = temp.replace(u"\U0001F3FD", "")
    temp = temp.replace(u"\U0001F195", "")
    temp = Functions.ToSQL(temp)
    return str(temp)

我不想为每个导致问题的角色都添加一行新行。通过这种方法,我已经能够传递多条tweet,但每个包含不同符号的tweet都会重新出现这个问题。难道没有一个解决方案可以过滤掉所有这些字符吗?是否可以过滤掉所有不在utf-8字符集中的字符?

尝试内置的unicode编码/解码错误处理功能:
str.encode(errors='ignore')

例如:

problem_string = """\
RT @John_Hunt07: Just voted for @marcorubio is Florida! I am ready for a New American Century!! #FLPrimary \ud83c\uddfa\ud83c\uddf8\ud83c\uddfa\ud83c\uddf8\ud83d\udc4d
"""
print(problem_string.encode(errors='ignore').decode('utf-8'))
忽略错误将删除有问题的字符

> RT @John_Hunt07: Just voted for @marcorubio is Florida! I am ready for a New American Century!! #FLPrimary 
其他错误处理选项可能会引起兴趣。 例如,
xmlcharrefreplace
将产生:

>RT@John\u Hunt07:刚刚投票给@marcorubio is Florida!我已经为新的美国世纪做好了准备#FLPrimary和#55356���������


如果您需要
UnicodeFilter
函数暗示的自定义筛选,请参阅。

尝试内置的unicode编码/解码错误处理功能:
str.encode(errors='ignore')

例如:

problem_string = """\
RT @John_Hunt07: Just voted for @marcorubio is Florida! I am ready for a New American Century!! #FLPrimary \ud83c\uddfa\ud83c\uddf8\ud83c\uddfa\ud83c\uddf8\ud83d\udc4d
"""
print(problem_string.encode(errors='ignore').decode('utf-8'))
忽略错误将删除有问题的字符

> RT @John_Hunt07: Just voted for @marcorubio is Florida! I am ready for a New American Century!! #FLPrimary 
其他错误处理选项可能会引起兴趣。 例如,
xmlcharrefreplace
将产生:

>RT@John\u Hunt07:刚刚投票给@marcorubio is Florida!我已经为新的美国世纪做好了准备#FLPrimary和#55356���������


如果您需要自定义筛选,如
UnicodeFilter
函数所示,请参阅。

Python提供了一个有用的堆栈跟踪,以便您可以判断错误的来源。 使用它,您会发现您的
打印
导致异常

print()
失败,因为您正在从Windows控制台运行Python,默认情况下,该控制台仅支持本地8位字符映射。您可以通过以下方式添加支持:

您也可以直接将数据写入文本文件。使用以下命令打开文件:

open('output.txt', 'w', encoding='utf-8')

Python提供了一个有用的stacktrace,这样您就可以知道错误来自何处。 使用它,您会发现您的
打印
导致异常

print()
失败,因为您正在从Windows控制台运行Python,默认情况下,该控制台仅支持本地8位字符映射。您可以通过以下方式添加支持:

您也可以直接将数据写入文本文件。使用以下命令打开文件:

open('output.txt', 'w', encoding='utf-8')

找到了答案。问题是推文中有一系列的字符造成了问题。找到字符的正确Unicode范围后,我实现了for循环以替换该范围内出现的任何Unicode字符。在实现这一点之后,我能够在没有任何格式或MySQL错误的情况下拉取数千条推文

@staticmethod
def UnicodeFilter(var):
    temp = var
    temp = temp.replace(chr(0x2019), "'")
    temp = temp.replace(chr(0x2026), "")
    for x in range(127381, 129305):
        temp = temp.replace(chr(x), "")
    temp = MySQLCL.ToSQL(temp)
    return str(temp)

找到了答案。问题是推文中有一系列的字符造成了问题。找到字符的正确Unicode范围后,我实现了for循环以替换该范围内出现的任何Unicode字符。在实现这一点之后,我能够在没有任何格式或MySQL错误的情况下拉取数千条推文

@staticmethod
def UnicodeFilter(var):
    temp = var
    temp = temp.replace(chr(0x2019), "'")
    temp = temp.replace(chr(0x2026), "")
    for x in range(127381, 129305):
        temp = temp.replace(chr(x), "")
    temp = MySQLCL.ToSQL(temp)
    return str(temp)

@theredcameron您的问题可能与Windows控制台有关,如中所述。@theredcameron您的问题可能与Windows控制台有关,如中所述。