Формат таблиц в pdf файлах за год несколько раз менялся. После того, как я понял, что надо каждый раз перестраивать парсеры строк, то понял, что даже, если у меня будет десяток разных парсеров для этого сайта, то я определенно в них запутаюсь. Надо записывать все в одном месте - и результаты, и код, и процесс отладки. Здесь я записал процесс перенастройки по файлу августа 2014 и научился наследовать собственный класс.
!chcp 65001
!dir C:\Users\kiss\Documents\Xpdf\aebru_2014_all_txt
Пропишем путь к рабочему модулю в переменную окружения¶
import sys
sys.path.append('C:\\Users\\kiss\\SkyDrive\\Docs\\pdftotext\\AEB\\pdgtotext')
sys.path
Вот он, последний, теперь импортируем все сюда
from aebto3tables import *
Проверим, вот константа из модуля:
CSVFOLDER
class August(Aebto3tables):
"""Try to tune august"""
#txtfile_path = 'C:\\Users\\kiss\\Documents\\Xpdf\\aebru_2014_all_txt\\eng_car-sales-in-august-2014.txt'
#csvfilename = 'eng_car-sales-in-august-2014.csv'
#
def alltxt2csv(self, path=TXTDATAFOLDER):
"""
The loop into folder with preliminary converted txt files
to call 1-3 tables parsers
Warning: it does not work if filename include additional
dots ('.') except file extension '.txt'
"""
for dir_entry in os.listdir(path):
if dir_entry.split('.')[1] == 'txt':
txtfile_path = os.path.join(path, dir_entry)
filename = dir_entry.split('.')[0]
#txtfilename = filename + r'.csv'
#csvfile_path = os.path.join(targetpath, txtfilename)
csvfilename = filename + r'.csv'
if os.path.isfile(txtfile_path):
self.tab1fromtxt(txtfile_path, csvfilename)
self.tab2fromtxt(txtfile_path, csvfilename)
self.tab3fromtxt(txtfile_path, csvfilename)
def tab1fromtxt(self, txtfile_path, csvfilename, csvfolder=CSVFOLDER):
"""
Первая таблица - самые продаваемые марки (50 строк)
Вот первые две:
Lada 151527 159490 -5% 44100 50102 -12%
Renault* 67208 57217 17% 19178 17914 7%
"""
t1 = []
with open(txtfile_path) as f1:
for line in f1:
if len(line.split()) in range(6, 9):
if (line.split()[-1].find('-') != -1) | (line.split()[-1].find('%') != -1):
if (line.split()[-4].find('-') != -1) | (line.split()[-4].find('%') != -1):
if (line.partition(' ')[2] != ['']) and (line.partition(' ')[0].strip() != 'Total'):
tline = []
tline.append(line.partition(' ')[0])
tline = tline + line.partition(' ')[2].split()
t1.append(tline)
csvfile_path = csvfolder + '\\1aug\\' + csvfilename
self.tocsv(t1, csvfile_path)
#print t1
def tab2fromtxt(self, txtfile_path, csvfilename, csvfolder=CSVFOLDER):
"""
Вторая - суммарные продажи по фирмам (все фирмы)
NISSAN 30,9 31,1 266169 274285 -3% 29,3 30,2 71977 80630 -12%
AVTOVAZ 17,6 18,1 151527 159490 -5% 18,0 18,8 44100 50102 -12%
"""
t2 = []
with open(txtfile_path) as f2:
for line in f2:
if len(line.split()) in range(12, 15):
if (line.split()[-1].find('-') != -1) | (line.split()[-1].find('%') != -1):
if (line.split()[-7].find('-') != -1) | (line.split()[-7].find('%') != -1):
if (line.partition(' ')[2] != ['']) and (len(line.partition(' ')[2].split()) == 12):
tline = []
tline.append(line.partition(' ')[0])
tline = tline + line.partition(' ')[2].split()
t2.append(tline)
csvfile_path = csvfolder + '\\2aug\\' + csvfilename
self.tocsv(t2, csvfile_path)
#print t2
def tab3fromtxt(self, txtfile_path, csvfilename, csvfolder=CSVFOLDER):
"""
Третья должна состоять из 25 строк вида:
1 Granta Lada 52765 26674 98% 15596 9798 59%
2 Solaris Hyundai 35941 38051 -6% 10553 10979 -4%
"""
t3 = []
with open(txtfile_path) as f3:
for line in f3:
if len(line.split()) in range(12, 16):
if line.split()[0].isdigit():
if (line.find(' ') != -1):
if (line.partition(' ')[2] != ['']) and (line.partition(' ')[0].isdigit()):
tline = []
tline.append(line.partition(' ')[0])
tline = tline + line.partition(' ')[2].split()
t3.append(tline)
csvfile_path = csvfolder + '\\3aug\\' + csvfilename
self.tocsv(t3, csvfile_path)
#print t3
txtfile_path = 'C:\\Users\\kiss\\Documents\\Xpdf\\aebru_2014_all_txt\\eng_car-sales-in-august-2014.txt'
csvfilename = 'eng_car-sales-in-august-2014.csv'
A = August('2014-08')
Сам по себе алгоритм отладки не очень удобный, но этот файл .ipynb потом можно использовать, как парасер.¶
- Правишь код в классе In[53]
2. Инициируешь классе In[53]
3. Создаешь экземпляр In[54]
5. Запускаешь метод In[22]
4. Но сначала присваиваешь значения параметрам метода In[16]
Внимание! папки для записи файлов задаются в трех подпрограммах в строках:¶
csvfile_path = csvfolder + '\\1aug\\' + csvfilename
csvfile_path = csvfolder + '\\2aug\\' + csvfilename
csvfile_path = csvfolder + '\\3aug\\' + csvfilename
Однако, записывать результаты еще рано, сначала в каждой подпрограмме отключим запись в файл и зададим вывод на печать:
# Должно быть при отладке
#csvfile_path = csvfolder + '\\3\\' + csvfilename
#self.tocsv(t3, csvfile_path)
print t3
Ниже результаты для каждой подпрограммы.¶
A.tab1fromtxt(txtfile_path, csvfilename)
A.tab2fromtxt(txtfile_path, csvfilename)
Ниже пример ошибки, для ее исправления нужно исправить код в классе и проделать всю процедуру (кроме присвоения параметров In[16]) сначала.
A.tab3fromtxt(txtfile_path, csvfilename)
Если сразу не догадался, где ошибка, то можно взять фрагмент (строку) из исходного текстового файла и поэлементно проверить код:
line = "1 Granta Lada 11,860 14,951 (3,091) 1 Granta Lada 95,154 113,738 (18,584) "
line.partition(' ')
line.partition(' ')[0].isdigit()
line.partition(' ')[0].split()[0].isdigit()
Оказалось, что я просто переусердствовал со скобками, без них все работает. Однако, оставимся на упрощенном варианте In [46]
Меняем код, опять нажимаем три раза на кнопку Run (для трех вышеупомянутых ячеек) и получаем наконец:
A.tab3fromtxt(txtfile_path, csvfilename)
Теперь убираем отладочную печать, раскоментируем строки и записываем результаты в папки 1aug, 2aug. 3aug¶
# Было при отладке
#csvfile_path = csvfolder + '\\3\\' + csvfilename
#self.tocsv(t3, csvfile_path)
print t3
# Стало (см выше в трез подпрограммах)
csvfile_path = csvfolder + '\\3aug\\' + csvfilename
self.tocsv(t3, csvfile_path)
#print t3
Вручную создаем папки 1aug, 2aug. 3aug
# Запускаем на выполнение
A.alltxt2csv()
Посты чуть ниже также могут вас заинтересовать
Комментариев нет:
Отправить комментарий