Предположим, что мы скачиваем CSV файл. Нам нужно определить папку (путь) для записи и как-то назвать этот файл. Ранее мы подготовили соглашение о наименованиях (далее по тексту "СН") и собираемся ему следовать. Здесь мы проверим код для соответствующих функций на языке Python.
Все было бы просто, если бы не наше решение о формировании имен файлов и использовании шаблонов URL. Однако, для хранения большого количества файлов - это необходимость.
Необходимы также и служебные файлы в некоторых папках (.info .log), но эту часть СН мы обсудим в других постах.
Необходимы также и служебные файлы в некоторых папках (.info .log), но эту часть СН мы обсудим в других постах.
В предыдущем посте Формируем список URL для скачивания файлов CSV со счетчика мы использовали шаблон строки URL для выбора скачиваемых файлов.
Здесь мы будем исходит из того, что скачивание (по списку файлов) происходит асинхронно (т.е. порядок скачивания из списка может нарушатся). В этом случае нам нужно будет придерживаться следующей последовательности действий:
Здесь мы будем исходит из того, что скачивание (по списку файлов) происходит асинхронно (т.е. порядок скачивания из списка может нарушатся). В этом случае нам нужно будет придерживаться следующей последовательности действий:
- Сначала нам нужно будет получить URL скачанного файла.
- Распарсить URL
- Каждой части URL поставить в соответсвие подстроку нового имени
- Сцепить все подстроки нового имени в соответствии с СН
- Задать полный путь для сохранения нового файла.
- Внести запись в соответствующий лог-файл.
Предположим, что скачиваем файлы с помощью библиотеки Grab на GitHub
Для справки нам может понадобиться примеры библиотеки furl Примеры и описание из репозитория библиотеки furl на GitHub Ниже варианты импорта библиотек:
Для справки нам может понадобиться примеры библиотеки furl Примеры и описание из репозитория библиотеки furl на GitHub Ниже варианты импорта библиотек:
In []:
from grab.spider import Spider, Task
# from grab import Grab # do not need if we use import Spider
In [1]:
# Добавимв импорт Selector from grab.selector import Selector
from furl import furl #url parser
1. URL скачанного файл¶
In []:
# create furl object from grab response url
fr= furl(grab.response.url)
In [2]:
# we use simple string instead previous grab.response.url
sample_url='http://top.mail.ru/pages.csv?id=85837&period=2&date=2013-12-17&sf=0&pp=20&filter_type=0&filter=catalogue/nissan&gender=0&agegroup=0&'
fr= furl(sample_url)
Здесь постараемся обойтись без библиотеки grab, а потому просто зададим пример строки sample_url из предыдущего поста. Посмотрим, как бибилиотека furl разберет эту строку. Ранее мы уже это делали (Постановка задачи "Парсинг URL в csv таблице" (итерация 1 продолжение)), но здесь поробуем уточнить все детали:
2. Распарсить URL¶
In [5]:
help(furl)
In [6]:
# scheme://username:password@host:port/path?query#fragment
fr.scheme, fr.path,
Out[6]:
In [12]:
sample_url
Out[12]:
In [14]:
fr.host, fr.path, fr.pathstr
Out[14]:
In [11]:
fr.args['id'], fr.args['period'], fr.args['date'], fr.args['filter'], fr.args['gender'], fr.args['agegroup'],
Out[11]:
3. Каждой части URL поставить в соответсвие подстроку нового имени¶
В этом посте мы определили первоначальный шаблон строки имени Как создать структуру папок. Скрипты и правила (соглашения о наименованиях)b Скопируем оттуда предполагаемое имя файла:
In []:
# Шаблон для имен файлов
_f_catlogue-nissan_y_2013_m_1-2-3-4_g_m-w_a_18-30-45-60_cm_comment_
# _f_ строка фильтра с заменой "/" на "_"
# _y_ год
# _m_ список месяцев через "-"
# _g_ пол список литералов-строк (m,w)
# _a_ возраст - цифры обозначают верхнюю границу интервала
# _cm_ комментарий - дополнительное поле
# для парсинга подстроки _m_ используется конструкция _m_*_
# длина переменной может изменятся
# порядок переменных важен не всегда
Выглядит довольно уныло... Напомню, что это строка имени для СУММАРНОГО файла, а мы здесь рассмтриваем первичные файлы. Сейчас надо определить, как именовать сохраняемые файлы.
1. Мы можем просто заменить в строках слеши (/)на (-) дефисы.
2. Или привести файлы к единому виду, который даст преимущества при последующе обработке.
1. Мы можем просто заменить в строках слеши (/)на (-) дефисы.
2. Или привести файлы к единому виду, который даст преимущества при последующе обработке.
In [25]:
su=sam ple_url.split('//')
su=su[1].replace('/','-')
print su
При самой простой замене нам все равно нужно посмотреть, что там за символы в строке, как их заменит (windows это любит) операционная система. Вот наверху пример, нам здесь пришлось убирать 'http://', но все равно имя файла содержит непривычные символы.
И самое главное, мы ведь будем работать с разными сайтами (счетчиками), потому все приводить к единому формату очень заманчиво... Попробуем!
И самое главное, мы ведь будем работать с разными сайтами (счетчиками), потому все приводить к единому формату очень заманчиво... Попробуем!
4. Сцепить все подстроки нового имени в соответствии с СН¶
Соглашение о наименовании файлов - строка шаблона. По сути вопрос в том, как преобразовать подстроки из URL в подстроки шаблона. Для этого нужны будут (среди прочего) и замены одних подстрок на другие. Потому начнем со словарей.
In []:
# Напишем код для преобразования в этот Шаблон для имен файлов
_f_catlogue-nissan_y_2013_m_1-2-3-4_g_m-w_a_18-30-45-60_cm_comment_
In [62]:
# Define Dictionaries
agegd = {"0":"All", "1":"до 12","2":"12-18","3":"19-24","4":"25-30","5":"31-35",
"6":"36-40","7":"41-45","8":"46-50","9":"over 50 "}
genderd = {"0":"All", "1":"Male","2":"Female"}
Наконец-то пришло время использовать словари. Как "перевести" символ возраста из "0" в "all"? Мы используем вот такую конструкцию:
In [66]:
# Словарь позволяет заменить Значение "0" из строки URL на его расшифровку
fr.args['agegroup'], agegd[fr.args['agegroup']]
Out[66]:
In [63]:
# Replace and convert
_f_=fr.args['filter'].replace('/','-')# catalogue-nissan
_y_=fr.args['date'].split('-')[0] #2013 -12-17
_m_=fr.args['date'].split('-')[1] #2013 -12- 17
_g_=genderd[fr.args['gender']] # gd = {'0':'all','1':'m','2':'w'}
_a_=agegd[fr.args['agegroup']]
_cm_= 'test'
In [64]:
fname='_f_'+_f_+'_y_'+_y_+'_m_'+_m_+'_g_'+_g_+'_a_'+_a_+'_cm_'+_cm_+'_'
fname
Out[64]:
Как редактировать и проверять преобразования? Нам нужно иметь под рукой
1. значения aргументов URL строки (см. In [11])
2. шаблон имен файлов
3. словари (In [62])
1. значения aргументов URL строки (см. In [11])
2. шаблон имен файлов
3. словари (In [62])
Однако, этого не достаточно. Нужны еще тесты для каждой строчки (In [63]). И, конечно, нужен перехват ошибок в "боевом модуле"...
5. Задать полный путь для сохранения нового файла. 6. Внести запись в соответствующий лог-файл¶
Очевидно, что рассмотренные здесь процессы следует отнести к одной функции формирования строки. Полный путь мы будем задавать в другой (родительской) функции записи файлов. Об этом в следующем посте.
А запись строки в лог-файл - это еще одна отдельная функция (или класс), и предмет отдельного поста. Вот только пока не знаю, как скоро он опявится.
А запись строки в лог-файл - это еще одна отдельная функция (или класс), и предмет отдельного поста. Вот только пока не знаю, как скоро он опявится.
В заключение немного порассуждаем о настройках и ошибках.¶
Пока я настраивал файл пришлось скроллить эту страницу "вверх-вниз", бороться с синтаксическими ошибками... Но шаблон строки URL я запомнил, он у меня перед глазами третий день. Полагаю, что через пару месяцев я этот шаблон с удовольствием забуду. В случае сбоя, который произойдет через эти два месяца из-за того, что где-нибудь в URL изменят слеш или дефис, мне нужно будет быстро вспомнить шаблон строки и локализовать ошибку. Может быть сразу (заранее) сделать скрипт для отладки в Notebook?
Посты чуть ниже также могут вас заинтересовать
Комментариев нет:
Отправить комментарий