xmlFile = codecs.open("myfile.xml", "r", "cp1251" ) #это к примеру такая кодировка.. даже если cp866 поставить все равно лажа
xmlData = xmlFile.read()
print isinstance(xmlData, unicode)
Выводится TRUE.. Т.е. какую бы кодировку я не задавал.. все равно читает юникод почему-то (((
Расскажите ламеру как правильно это делается пожалуйста.
Да.. и потом то что получится я хочу конвертнуть в utf-8.. делаю так:
myutf = xmlData.encode('utf-8', 'ignore')
Это по идее должно работать, по крайней мере раньше проблем с этим не было..
Может подскажете как это сделать лучше.. если вообще возможно такое..
Я новичок в Пайтоне.. не откажусь от любой помощи
29.05.08 11:27: Перенесено модератором из 'Прочее' — Хитрик Денис
Здравствуйте, diatlov, Вы писали:
D>Я новичок в Пайтоне.. не откажусь от любой помощи
Совершенно не разбираясь в ситуации ...
Видимо дело в том, что функция open — читает в указанной кодировке, но в конечном итоге конвертирует в кодировку по умолчанию — unicode.
C Уважением, Andir!
Здравствуйте, GonzoVas, Вы писали:
GV>Здравствуйте, diatlov, Вы писали:
D>>Выводится TRUE.. Т.е. какую бы кодировку я не задавал.. все равно читает юникод почему-то (((
GV>я думаю, можно не волноваться, unicode означает внутреннее представление строки.
GV>кодировки в open влияют на содержимое этой строки — чтоб кракозябр не было
Насчет "НЕ ВОЛНОВАТЬСЯ" не соглашусь с вами. Специфика программы такова, что как раз юникодная строка там была совершенно ни к чему.
Объясняю. Пайтон 2.5
Для парсинга XML и создания dom есть 2 функции: xml.dom.minidom.parse и xml.dom.minidom.parseString
Первая функция создает dom нормально но не дает желаемой глубины контроля (если конкретно, то я не могу задать ей кодировку, в которой она должна читать и сохранять данные).
Вторая функция более гибкая... на первый взгляд. Почитав доки и сообщения на форумах узнал, что оказывается она НЕ РАБОТАЕТ с unicode.
Соответственно надо выкручиваться было.
После плясок с бубном и 15-20 ударами головой об стол меня осенила идея как сделать необходимую.. почти такую как надо функциональность с использованием первой функции.
Так и быть.. расскажу что за прога.. и даже дам поюзать код.
Программа парсит xml файл и сливает данные из него в мускулувскую базу. Все настройки сидят в конфиге. Короче тот кому надо разберется.
Ниже полный код программы на Пайтоне и пример конфига для неё.
# -*- coding: utf-8 -*-
import sys, xml.dom.minidom, ConfigParser, MySQLdb, codecs
myCfg = ConfigParser.ConfigParser()
myCfg.read("config.ini")
db = MySQLdb.connect(host=myCfg.get("options", "db_host"), user=myCfg.get("options", "db_user"), passwd=myCfg.get("options", "db_pass"),
db=myCfg.get("options", "db_DB"))
cursor = db.cursor()
table = myCfg.get("options", "db_table")
dom = xml.dom.minidom.parse(myCfg.get("options", "xmlfile"))
tempList = myCfg.items("fields")
elementsList = {}
for t in tempList:
elementsList[t[1]] = t[0]
elements = dom.getElementsByTagName(myCfg.get("options", "xmlbase"))
ready = 1
for element in elements:
mylist = {}
for e in elementsList.keys():
els = element.getElementsByTagName(e)
for elm in els:
for t in elm.childNodes:
mylist[e] = t.data
break
break
fields = ""
values = ""
for field in mylist.keys():
fields += elementsList[field]+","
values += "'"+mylist[field].replace('\'', '\\''')+"',"
query = "INSERT INTO "+table+" ("+fields.rstrip(',')+") VALUES ("+values.rstrip(',')+")"
print query.encode(sys.stdout.encoding, 'ignore')
cursor.execute(query.encode('utf-8', 'ignore'))
print ("ready "+str(ready)+" records").encode(sys.stdout.encoding, 'ignore')
ready = ready + 1
db.commit() # эту штуку можно делать к примеру каждые 100 записей или можно вообще в конец вынести.. Если скорость не критична, то можно и так.
cursor.close()
db.close()
А вот и конфиг (в конфиге в секции fields сидят соответствия полей БД и тегов xml файла. xmlbase — блок содержимое которого неоходимо отпарсить):
[options]
db_host = localhost
db_user = root
db_pass = 123
db_DB = shopbase
db_table = shop
xmlfile = soft.xml
xmlbase = offer
xmlencoding = cp1251
[fields]
shop_url = url
shop_price = price
shop_currencyId = currencyId
shop_picture = picture
shop_ordering = ordering
shop_name = name
shop_vendor = vendor
shop_description = description
Пример файла (отрывок), содержимое которого она парсит:
<?xml version="1.0" encoding="windows-1251"?>
<!DOCTYPE yml_catalog SYSTEM "shops.dtd">
<yml_catalog date="2008-04-11 22:03">
<shop>
<name>Интернет-магазин оЗон</name>
<company>ООО "оЗон"</company>
<url>http://www.ozon.ru/</url>
<currencies>
<currency id="RUR" rate="1" />
</currencies>
<categories>
//тут чего-то ещё.. не важно
</categories>
<offers>
<offer id="1664564">
<url>http://www.ozon.ru/context/detail/id/1664564/?from=partner</url>
<price>180</price>
<currencyId>RUR</currencyId>
<categoryId>7312</categoryId>
<categoryId>1081623</categoryId>
<picture>http://www.ozon.ru/multimedia/audio_cd_covers/1000119351.jpg</picture>
<orderingTime>
<ordering>В течение недели</ordering>
</orderingTime>
<name>Прогулки по Лувру</name>
<vendor>МедиаХауз</vendor>
<description>Один из самых известных музеев мира открывает перед вами свои двери, приглашая взглянуть на шедевры скульптуры и живописи. Сопровождать по залам старинного дворца вас будут замечательные ведущие - Лили и Пьер. Они помогут вам изучить более 150</description>
</offer>
<offer id="1664605">
<url>http://www.ozon.ru/context/detail/id/1664605/?from=partner</url>
<price>180</price>
<currencyId>RUR</currencyId>
<categoryId>7253</categoryId>
<picture>http://www.ozon.ru/multimedia/audio_cd_covers/1000119337.jpg</picture>
<orderingTime>
<ordering>В течение недели</ordering>
</orderingTime>
<name>Космокролик. Rocket Rabbit. Кто подставил космо кролика?</name>
<vendor>Акелла</vendor>
<description>И снова красочные аркадные игры зашагали на наших экранах! Перед вами проект "Космокролик"! В полностью трехмерной среде вам предстоит быть кроликом. Да не простым, а поедающим радиоактивную морковку и вооруженным лазерной пушкой! Ваша</description>
</offer>
<offer id="1664620">
<url>http://www.ozon.ru/context/detail/id/1664620/?from=partner</url>
<price>180</price>
<currencyId>RUR</currencyId>
<categoryId>7253</categoryId>
<picture>http://www.ozon.ru/multimedia/audio_cd_covers/1000119345.jpg</picture>
<orderingTime>
<ordering>На складе</ordering>
</orderingTime>
<name>Crazy Taxi 3: Безумный таксист</name>
<vendor>Акелла</vendor>
<description>Люди вечно куда-то спешат, снуют по городу днем и ночью... Они ловят такси, и оно доставляет их в нужное место. Визг тормозов, рев двигателя - это несется безумный кабриолет сумасшедшего водителя, готового ради каждой секунды сжечь покрышки своих</description>
</offer>
//такого добра несколько тысяч блоков может быть
</offers>
Вот такая маленькая простая программа вышла ) для парса таких сложных огромных xml'ей.
Если у вас есть предложения по улучшению, или вы хотите как-то развить это дело, пишите мне в асю 488880111, или на мыло s-soft@list.ru или сюда в ветку. Буду рад каждому сообщению и предложению.
Здравствуйте, diatlov, Вы писали:
Ужжос!
Выдели функции, а то всё в перемешку.
Используй тег раскраски для python-а
Переноси длинные строки — читать невозможно.
Используй списковые дополнения — они нагляднее. Например elementsList можно заполнить проще:
elementsList = dict(
(tag, fld) for fld, tag in myCfg.items("fields"))
Как и mylist, fields, values
Для форматирования строк используй % — нагляднее, например:
query = "INSERT INTO %s (%s) VALUES (%s)" % (table, fields.rstrip(','), values.rstrip(','))
Для сцепления строк через разделитель используй метод строки join. Например, если хочешь из списка строк получить строку разделённую , используй
','.join(fileds)
Используй запросы с параметрами — не надо заботится о ковычках в строках и форматах значений. К тому же они работают быстрее.
Если использовать запрос с параметрами, его можно создать всего 1 раз — перед циклом
Если подряд выполняется несколько одинаковых запросов — можно использовать executemany вместо execute — опять же ускорение.
... << RSDN@Home 1.2.0 alpha 4 rev. 1065>>
Да уж! Вот так пайтон.
Я в пайтоне новичок, поэтому не особо разбираясь
в тонкостях языка, написал как мог, а мог на Си++.
Соответственно и код пайтоновский приближал к Си.
Хороших мануалов по пайтону не видел, поэтому читал
доки к нему в стандартной поставке.
Кстати они там по моему мало информативные (для 2.5.1 . Для 3.0 супер)
По поводу раскраски кода, так в редакторе нету подсветки для пайтона.
А строки длинные — так у меня монитор 19 дюймов wide. У меня все помещаетсяя
Хотя я с мускулом работаю достаточно плотно и хорошо, не знал о возможности
функции executemany. Но я так понимаю, эта функция искусственная,
и специфична для пайтоновской библы.
Огромное спасибо за ваш содержательный комментарий!