2017-02-07 17 views
0

Я собираю персидские твиты под управлением следующий код Python:Преобразование сырой текст ASCII с UTF-8 кодируются символы, представленные восьмеричные

#!/usr/bin/env python 
# -*- coding: UTF-8 -*- 
import sys 
import tweepy 
import json 
import os 

consumer_key ="xxxx" 
consumer_secret ="xxxx" 
access_key = "xxxx" 
access_secret = "xxxx" 

auth = tweepy.OAuthHandler(consumer_key, consumer_secret) 
auth.set_access_token(access_key, access_secret) 
api = tweepy.API(auth) 

save_file = open("Out.json", 'a') 

t1 = u"" 

class CustomStreamListener(tweepy.StreamListener): 
    def __init__(self, api): 
     self.api = api 
     super(tweepy.StreamListener, self).__init__() 

     # self.list_of_tweets = [] 

    def on_data(self, tweet): 
     print tweet 
     save_file.write(str(tweet)) 

    def on_error(self, status_code): 
     print >> sys.stderr, 'Encountered error with status code:', status_code 
     return True # Don't kill the stream 
     print "Stream restarted" 

    def on_timeout(self): 
     print >> sys.stderr, 'Timeout...' 
     return True # Don't kill the stream 
     print "Stream restarted" 

def start_stream(): 
    while True: 
     try: 
      sapi = tweepy.streaming.Stream(auth, CustomStreamListener(api)) 
      sapi.filter(track=[t1]) 
     except: 
      continue 

start_stream() 

Он возвращает чириканье текст в текстовый файл с UTF-8 закодированных символов, представленных обратная косая черта. Я хотел бы изменить код таким образом, который непосредственно сохраняет извлеченные твиты в «Out.json» в кодированном формате UTF-8.

{ 
    "created_at": "Tue Feb 07 08:04:17 +0000 2017", 
    "id": 828877025049972737, 
    "id_str": "828877025049972737", 
    "text": "\u0644\u0637\u0641\u0627 \u0628\u0647 \u062d\u06cc\u0648\u0627\u0646\u0627\u062a \u063a\u06cc\u0631\u062e\u0627\u0646\u06af\u06cc \u063a\u0630\u0627\u00a0\u0646\u062f\u0647\u06cc\u062f https:\/\/t.co\/gFi5XCVQww https:\/\/t.co\/pQWPqbvJVF", 
    "display_text_range": [0, 58], 
    "source": "\u003ca href=\"http:\/\/publicize.wp.com\/\" rel=\"nofollow\"\u003eWordPress.com\u003c\/a\u003e", 
    "truncated": false, 
    "in_reply_to_status_id": null, 
    "in_reply_to_status_id_str": null, 
    "in_reply_to_user_id": null, 
    "in_reply_to_user_id_str": null, 
    "in_reply_to_screen_name": null, 
    ... 
    "lang": "fa", 
    "timestamp_ms": "1486454657219" 
} 
+0

Это * правильные данные JSON *. Я не уверен, чего вы ожидали. Что вы хотели видеть спасенным? Обратите внимание, что UTF-8 является * надмножеством * ASCII, поэтому ** все ** символы есть UTF-8. Если вы хотите сгенерировать JSON без экранов '\ uhhhh' (так что сохраните необработанный символ как байты UTF-8, а не escape-последовательность JSON), тогда вам придется декодировать и перекодировать. См. [Сохранение текстов utf-8 в json.dumps как UTF8, а не как escape-последовательность] (// stackoverflow.com/q/18337407) –

ответ

0

Метод StreamListener.on_data() передается необработанные данные в формате JSON, как получил из Twitter. Именно эти данные содержат допустимые escape-последовательности JSON.

Если вы хотите сохранить данные UTF-8 непосредственно, так и с \uhhhh экранирующие последовательности заменяются фактической Unicode элемент кода, вам придется перекодировки чирикать. Используйте Saving utf-8 texts in json.dumps as UTF8, not as \u escape sequence для сохранения данных впоследствии.

Обратите внимание, что запись нескольких объектов JSON в один файл делает этот файл недействительным JSON. Вы можете создать JSON Lines output, введя новые строки (стандартный вывод json.dumps() не создает новые строки в сгенерированном документе JSON), затем читайте эти записи один за другим с помощью this answer.

Так важные разделы вашего кода должен выглядеть следующим образом:

import json 

save_file = open("Out.json", 'a') 

class CustomStreamListener(tweepy.StreamListener): 
    # ... 

    def on_data(self, tweet): 
     tweet = json.loads(tweet) 
     json_doc = json.dumps(tweet, ensure_ascii=False) 
     save_file.write(json_doc.encode('utf8') + '\n') 
0

str Удалить вызов:

# ... 

def on_data(self, tweet): 
    print tweet 
    save_file.write(tweet) 

# ... 

Если это не поможет, откройте файл с помощью codecs модуля:

save_file = codecs.open("Out.json", 'a', encoding="utf-8") 
+0

Не используйте 'codecs.open()'; скорее используйте 'io.open()'; это структура Python 3, которая * намного более надежна, чем структура 'codecs'. –

+0

Спасибо за ответ. Удалено «str», но нет успеха. – farlay

+0

@farlay: это потому, что ваши данные ** уже закодированы JSON **, уже строка. –