2013-06-24 1 views
0

Я пытаюсь использовать Python для создания коллекции таблиц HTML со значениями, выведенными из CSV. Скрипт работает нормально, однако это добавление в нечетных «¬ †» символов, где значение втягивается вPython Вставка нежелательных символов

Это код, который я использовал, чтобы захватить данные CSV:.

import csv 
import fileinput 
import re 

out=open("audiencestats.csv","rU") 
data=csv.reader(out) 
values =[row for row in data] 
metrics = values.pop(0) 
out.close() 

Это создает функцию сделать HTML таблицы:

def maketable(leftmetric, rightmetric, leftvalue, rightvalue): 
    template = ''' 
    <table width="99%%" border="1"> 
    <tbody> 
    <tr> 
    <td align="center" valign="middle"> 
    <h3>%s</h3> 
    </td> 
    <td align="center" valign="middle"> 
    <h3>%s</h3> 
    </td> 
    </tr> 
    <tr> 
    <td align="center" valign="middle"> %s</td> 
    <td align="center" valign="middle"> %s</td> 
    </tr> 
    </tbody> 
    </table> 
    ''' 
    file.write(template % (leftmetric, rightmetric, leftvalue, rightvalue)) 

Тогда это пишет таблицы в текстовые файлы:

for i in values: 
    filename = "%s.txt" % i[0] 
    file = open(filename , 'w') 
    file.write(header) 
    maketable(metrics[1],metrics[2],i[1],i[2]) 
    maketable(metrics[3],metrics[4],i[3],i[4]) 
    maketable(metrics[5],metrics[6],i[5],i[6]) 
    maketable(metrics[7],metrics[8],i[7],i[8]) 
    maketable(metrics[9],metrics[10],i[9],i[10]) 
    maketable(metrics[11],metrics[12],i[11],i[12]) 
    file.write(header2) 
    print makesocial(i[13],i[14],i[15]) 
    file.close() 

Я попытался добавить в нижний re.sub цикл for, но кресты остаются.

for line in fileinput.input(inplace=1): 
    line = re.sub(' ','', line.rstrip()) 
    print(line) 

Я что-то не хватает? Мой компьютер стал религиозным?

Пример вывода скопированный ниже, а также:

<h1>Audience</h1> 
    <table width="99%" border="1"> 
    <tbody> 
    <tr> 
    <td align="center" valign="middle"> 
    <h3>UVs (000)</h3> 
    </td> 
    <td align="center" valign="middle"> 
    <h3>PVs (000)</h3> 
    </td> 
    </tr> 
    <tr> 
    <td align="center" valign="middle"> 580.705</td> 
    <td align="center" valign="middle"> 1003</td> 
    </tr> 
    </tbody> 
    </table> 
+1

Является ли это символом валюты Unicode? Что находится в файле CSV? Каковы двоичные значения двух символов? –

+1

Это пахнет проблемой кодирования. Какая кодировка является файлом CSV? Можете ли вы загрузить (небольшую выборку) где-нибудь или просто открыть его как двоичный файл и 'print ('.join (hex (ord (c)) для c в f.readline()))' или подобное? – abarnert

+1

Кроме того, почему вы пытаетесь использовать 're.sub' для замены фиксированной подстроки? Для этого просто используйте 'str.replace'. – abarnert

ответ

0

Нет ничего плохого в ваших данных - это чистый ASCII. Проблема в исходном коде.

Нажав кнопку «Изменить», чтобы скопировать фактический источник, а не ваш форматированный источник, он имеет символы неразрывного пробела (U + 00A0) в середине строкового литерала template.

Предполагая, что ваш редактор и браузер, с которого вы скопировали и вставляли их, делали все правильно, это означает, что ваш фактический источник UTF-8 имеет последовательности '\xc2\xa0'.

Поскольку вы помещаете не-ASCII символы в str/bytes буквальных (который, как я уже говорил в другом ответе, это всегда плохая идея), то это означает, что ваши строки в конечном итоге с '\xc2\xa0' последовательностями.

Где-то между этим и вашим экраном есть дополнительная проблема с кодированием, и это становится искаженным в последовательности '\xc2\xac\xe2\x80\xa0', которые, если они интерпретируются как UTF-8, отображаются как u'¬†'.

Мы могли бы попытаться отследить, откуда эта дополнительная проблема, но это не имеет большого значения.

Непосредственное решение заключается в замене всех неразрывных пространств в вашем источнике на простые ASCII-пространства.

Выходя за пределы этого, вам нужно выяснить, что вы использовали, создавая эти неразрывные пробелы. Часто это признак редактирования исходного кода в текстовых редакторах, а не текстовых редакторах; если это так, прекратите это делать.

Если у вас на самом деле нет преднамеренно-не-ASCII-кода, используя # coding=ascii вместо # coding=utf-8 в верхней части файла, это отличный способ поймать такие ошибки. (Вы все еще можете обрабатывать значения UTF-8, все декларация кодирования говорит о том, что сам исходный код находится в UTF-8.)

+0

Отлично! Это получилось. Если вы посмотрите в исходном коде выше в функции maketable, на строке появится дополнительное пространство, которое читает '% s' Пробел перед '% s 'превращался в крест. Очень ценим! – nslamberth

-1

Попробуйте это:

line = re.sub(r'(?u) ','', line.rstrip()) 

Тогда регулярное выражение лечить вашу строку как юникода.

+0

Все флагом 're.UNICODE' /'? U' изменяет способ использования встроенных классов символов. См. [Документы] (http://docs.python.org/2/library/re.html#re.UNICODE). Кроме того, как правило, это плохая идея использовать '? U' с строками шаблонов без Unicode. – abarnert

+0

Пробовал это, не кубик :( – nslamberth

0

Вы все еще не отвечали на вопросы, которые я просил разъяснить, поэтому я собираюсь угадать здесь.

Во-первых, причина вашей re.sub не работает, что ваш шаблон является UTF-8 ¬† ('\xc2\xac\xe2\x80\xa0'), но вы пытаетесь соответствовать CP1252 ¬† ('\xac\x86'). Очевидно, что они не совпадают.

Во-вторых, причина, по которой вы получаете этот мусор в первую очередь, заключается в том, что ваш файл CSV обрабатывается тем, что не использует UTF-8, даже если вы так думаете. Возможно, это ваша электронная таблица, текстовый редактор или инструмент командной строки.

Скорее всего, вы только что перепутали одну 8-битную кодировку с другой на каком-то этапе по цепочке, выписали какой-то текст как cp1252, а затем попытались отредактировать его как UTF-8 или наоборот.

Но это довольно интересно. Это U + 2020. Если у вас есть текст UTF-16-LE и отредактируйте его как UTF-8 (или ASCII или cp1252), и попробуйте добавить пару пробелов, вы фактически добавляете один U + 2020. Обычно вы считаете, что будет сложно смешивать UTF-16 и UTF-8. Но ясно, что вы просто просматриваете текст, а не смотрите на байты, и если все ваши данные вписываются в Latin-1, UTF-16 будет отлично смотреться до вашего глазного яблока, есть невидимый символ NUL после каждого реального характер, но вы не можете видеть невидимые вещи.

В любом случае, не имеет значения, какие именно детали. Единственный способ исправить это - посмотреть на фактические байты в файле, сгенерированном на каждом шаге в цепочке, узнать, где вы делаете это неправильно, и исправить его соответствующим образом. Если вы не знаете, как это сделать, вам нужно предоставить другим людям достаточную информацию, чтобы сделать это за вас.

Однако, если вы просто хотите быстро обходное решение: возьмите файл, который вы загружаете в свой скрипт Python, и просмотрите его в шестнадцатеричном редакторе. Найдите два символа мусора и запишите, какими байтами они являются.Если они, скажем, ac 86, просто измените свой код, чтобы сделать s = s.replace('\xac\x86', '').

+0

Благодарим за углубленный анализ, очень просвещаем. Я открыл CSV в шестнадцатеричном редакторе (Hex Fiend), но не вижу символов мусора. точки отделяются «2C», который выдается как запятая, но нет следов ¬ †. Я попытался заменить '\ xac \ x86' и '\ xc2 \ xac \ xe2 \ x80 \ xa0', но символы все еще отображаются. Вот несколько строк шестнадцатеричных кодов, которые я получил, открыв csv как двоичную и бегущую печать ('.join (hex (ord (c)) для c в f.readline())), как вы сказали, я опубликовал их в следующем комментарии. – nslamberth

+0

'0x32 0x25 0x2c 0x33 0x30 0x2e 0x37 0x36 0x33 0x2c 0x38 0x33 0x2c 0x35 0x30 0x38 0x2c 0x33 0x31 0x35 0x2e 0x34 0x36 0x39 0x2c 0x38 0x32 0x25 0x2c 0x2c 0x2c 0 x2c 0x2c 0x35 0x36 0x2c 0x35 0x37 0x38 0x39 0x2c 0x37 0x37 0x38 0x30 0xd 0x50 0x6f 0x74 0x68 0x6f 0x6c 0x65 0x73 0x20 0x49 0x6e 0x20 0x4d 0x79 0x20 0x42 0x6c 0x6f 0x67 0x2c – nslamberth

+0

Нет никаких странных символов, которые находятся далеко в файле (это заканчивается с 'Potholes In My Blog ', если это помогает). В частности, это все еще часть первой строки, которая используется для 'metrics', а не' i', и кажется, что странные символы появляются в значениях 'i', поэтому ... Можете ли вы опубликовать весь файл где-нибудь, или hexdump большего исходного фрагмента, чем это? – abarnert