2017-12-10 2 views
0

tweepy를 사용하여 파이썬 csv.writer(을 사용하여 CSV 파일에 트윗 텍스트를 저장했지만, 저장하기 전에 utf-8로 텍스트를 인코딩해야했습니다. 그렇지 않으면 tweepy가 이상한 오류를 발생시킵니다.csv에서 bytes 객체를 읽는 방법?

이제 텍스트 데이터는 다음과 같이 저장됩니다 :이이 코드를 사용하여 디코딩을 시도

"b'Lorem Ipsum\xc2\xa0Assignment '" 

(텍스트가 3 열에있는 다른 컬럼에 데이터가 더) :

with open('data.csv','rt',encoding='utf-8') as f: 
    reader = csv.reader(f,delimiter=',') 
    for row in reader: 
     print(row[3]) 

그러나 텍스트를 디코딩하지는 않습니다. csv 리더가 데이터를 문자열 (예 : type(row[3]))이 'str' 인 것으로 읽음에 따라 을 사용할 수없고 데이터를 bytes으로 변환 할 수없는 경우 데이터가 한 번 더 인코딩됩니다.

어떻게 텍스트 데이터를 디코딩 할 수 있습니까?

편집 : 여기에 csv 파일의 샘플 라인이다 :

67783591545656656999,3415844,1450443669.0,b'Virginia School District Closes After Backlash Over Arabic Assignment: The Augusta County school district in\xe2\x80\xa6 | @abcde',52,18 

참고 :이 솔루션은 인코딩 과정에 있다면, 내가 다시 전체 데이터를 다운로드하는 것을 여유가있을 수 있음을 유의하시기 바랍니다.

+0

텍스트 편집기에서 해당 파일을 열면 나타나는대로 정확하게 파일에서 적어도 하나 개의 완전한 라인을 제시해주십시오 . 코드와 데이터가 모두 없으면 문제를 재현 할 수 없습니다. – BoarGules

+0

죄송합니다. 예제를 추가했습니다. 해당 줄을 확장명이 .csv 인 파일로 저장하십시오. – gitmorty

+0

그래서 csv 파일에는 문자 그대로 'b'Virginia ...'와 같이 'b'접두어가 붙은 문자열이 있습니다. – martineau

답변

1

실제로 입력 파일에 파이썬 구문 b 접두어가 포함 된 문자열이 포함되어있는 경우 해결 방법 중 하나는 (비록 실제로 CSV 데이터에 유효한 형식이 아니더라도) 파이썬의 ast.literal_eval 함수를 사용하는 것입니다. 나는 아래와 같이 약간 다른 방식으로 사용할 것입니다.

이렇게하면 b' 바이트 문자열 접두어가 추가 된 파일에있는 모든 문자열을 구문 분석 할 수있는 안전한 방법을 제공합니다. 나머지 필드는 변경되지 않고 전달됩니다.

import ast 
import csv 


def _parse_bytes(field): 
    """ Convert string represented in Python byte-string literal syntax into a 
    decoded character string. Other field types returned unchanged. 
    """ 
    result = field 
    try: 
     result = ast.literal_eval(field) 
    finally: 
     return result.decode() if isinstance(result, bytes) else field 

def fix_bytes(filename, delimiter=','): 
    with open(filename, 'rt') as f: 
     yield from (delimiter.join(_parse_bytes(field) 
             for field in line.split(delimiter)) 
              for line in f) 

filename = 'bytes_data.csv' 
reader = csv.reader(fix_bytes(filename)) 
for row in reader: 
    print(row[3]) 
+0

고맙습니다. 이것은 위의 경우를 해결하지만 eval()을 사용하는 것이 편안하지 않습니다. 헤더 문자열이 있기 때문에 심지어 내 파일에서 실패합니다. – gitmorty

+0

gitmorty : @ Ryan이'eval()'대신에'ast.literal_eval()'을 사용하는 아이디어는 좋은 생각이며 기본 아이디어를 내 답변에 포함 시켰다고 생각합니다. 논평. – martineau

1

안전하게 바이트로 다시 잘못된 필드를 변환 ast.literal_eval를 사용할 수 있습니다

import ast 


def _parse_bytes(bytes_repr): 
    result = ast.literal_eval(bytes_repr) 

    if not isinstance(result, bytes): 
     raise ValueError("Malformed bytes repr") 

    return result 
관련 문제