Извините.. Тупой вопрос по Python.
От: diatlov Молдова  
Дата: 13.04.08 19:50
Оценка:
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: Перенесено модератором из 'Прочее' — Хитрик Денис
Re: Извините.. Тупой вопрос по Python.
От: Andir Россия
Дата: 14.04.08 01:33
Оценка:
Здравствуйте, diatlov, Вы писали:

D>Я новичок в Пайтоне.. не откажусь от любой помощи


Совершенно не разбираясь в ситуации ...
Видимо дело в том, что функция open — читает в указанной кодировке, но в конечном итоге конвертирует в кодировку по умолчанию — unicode.

C Уважением, Andir!
Re: Извините.. Тупой вопрос по Python.
От: GonzoVas Россия  
Дата: 14.04.08 15:08
Оценка:
Здравствуйте, diatlov, Вы писали:

D>Выводится TRUE.. Т.е. какую бы кодировку я не задавал.. все равно читает юникод почему-то (((


я думаю, можно не волноваться, unicode означает внутреннее представление строки.
кодировки в open влияют на содержимое этой строки — чтоб кракозябр не было
Re[2]: Извините.. Тупой вопрос по Python.
От: diatlov Молдова  
Дата: 18.04.08 22:01
Оценка:
Здравствуйте, 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 или сюда в ветку. Буду рад каждому сообщению и предложению.
Re: Извините.. Тупой вопрос по Python.
От: Константин Б. Россия  
Дата: 22.04.08 14:21
Оценка:
Здравствуйте, diatlov, Вы писали:


D>
D>xmlFile = codecs.open("myfile.xml", "r", "cp1251" ) #это к примеру такая кодировка..  даже если cp866 поставить все равно лажа

D>xmlData = xmlFile.read()

D>print isinstance(xmlData, unicode)
D>


D>Выводится TRUE.. Т.е. какую бы кодировку я не задавал.. все равно читает юникод почему-то (((

D>Расскажите ламеру как правильно это делается пожалуйста.

D>Да.. и потом то что получится я хочу конвертнуть в utf-8.. делаю так:


D>
D>myutf = xmlData.encode('utf-8', 'ignore')
D>


D>Это по идее должно работать, по крайней мере раньше проблем с этим не было..

D>Может подскажете как это сделать лучше.. если вообще возможно такое..
D>Я новичок в Пайтоне.. не откажусь от любой помощи

А в чем собственно вопрос?
Re[3]: Извините.. Тупой вопрос по Python.
От: Tonal- Россия www.promsoft.ru
Дата: 23.04.08 14:28
Оценка: 3 (1)
Здравствуйте, diatlov, Вы писали:
Ужжос!
  1. Выдели функции, а то всё в перемешку.
  2. Используй тег раскраски для python-а
  3. Переноси длинные строки — читать невозможно.
  4. Используй списковые дополнения — они нагляднее. Например elementsList можно заполнить проще:
    elementsList = dict(
      (tag, fld) for fld, tag in myCfg.items("fields"))

    Как и mylist, fields, values
  5. Для форматирования строк используй % — нагляднее, например:
    query = "INSERT INTO %s (%s) VALUES (%s)" % (table, fields.rstrip(','), values.rstrip(','))

  6. Для сцепления строк через разделитель используй метод строки join. Например, если хочешь из списка строк получить строку разделённую , используй
    ','.join(fileds)

  7. Используй запросы с параметрами — не надо заботится о ковычках в строках и форматах значений. К тому же они работают быстрее.
  8. Если использовать запрос с параметрами, его можно создать всего 1 раз — перед циклом
  9. Если подряд выполняется несколько одинаковых запросов — можно использовать executemany вместо execute — опять же ускорение.
... << RSDN@Home 1.2.0 alpha 4 rev. 1065>>
Re[4]: Извините.. Тупой вопрос по Python.
От: diatlov Молдова  
Дата: 13.05.08 22:26
Оценка:
Да уж! Вот так пайтон.
Я в пайтоне новичок, поэтому не особо разбираясь
в тонкостях языка, написал как мог, а мог на Си++.
Соответственно и код пайтоновский приближал к Си.
Хороших мануалов по пайтону не видел, поэтому читал
доки к нему в стандартной поставке.
Кстати они там по моему мало информативные (для 2.5.1 . Для 3.0 супер)
По поводу раскраски кода, так в редакторе нету подсветки для пайтона.
А строки длинные — так у меня монитор 19 дюймов wide. У меня все помещаетсяя

Хотя я с мускулом работаю достаточно плотно и хорошо, не знал о возможности
функции executemany. Но я так понимаю, эта функция искусственная,
и специфична для пайтоновской библы.

Огромное спасибо за ваш содержательный комментарий!
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.