Поиск по блогу

пятница, 13 февраля 2015 г.

Фрагменты кода для парсере PDF (AEBto3tables)

Здесь я начал раздумывать о том, как сделать парсер pdf и попробовал осмыслить последовательность обработки папки с pdf файлами. Собрал сюда фрагманты работающего кода с os.listdir(path) subprocess.Popen(...) pdftotext , потом фильтры для трех таблиц (код фильтров надо переделать, не учел что в названии может быть несколько слов), потом великие открытия с sys.path.append(...) и прехватом сообщений дебаггера из консоли прямо в notebook...

Сначала я пытался решить общую задачу: спроектировать класс модуля парсера. Но по неопытности завяз в мелочах. Потом открыл Ninja и тупо навтыкал в класс подпрограммы из этих фрагментов. Но о результатах потом, здесь проверка работы фрагментов.

In []:
0. Код для организации цикла по именам файлов внутри папки [Фрагменты кода с os.listdir(path) и итерации по файлам в папке]()
In []:
# Задаем путь к папке с файлами
path = r'C:\abc\def\ghi'  # remove the trailing '\'

Все файлы из папки считываем в список os.listdir(path) к каждому файлу добавляем слева полный путь. А потом открываем файл и весь его загоняем в элемент словаря с ключом = имени файла в папке.

In []:
import os
data = {}
for dir_entry in os.listdir(path):
    dir_entry_path = os.path.join(path, dir_entry)
    if os.path.isfile(dir_entry_path):
        with open(dir_entry_path, 'r') as my_file:
            data[dir_entry] = my_file.read()
  1. CMD команда для преобразования pdf to text
In []:
!dir C:\Program Files\Xpdf\bin64\pdftotext.exe 
In [1]:
!dir C:\Users\kiss\Documents\Xpdf\aebru_2014_all
 ’®¬ ў гбва®©б⢥ C ­Ґ Ё¬ҐҐв ¬ҐвЄЁ.
 ‘ҐаЁ©­л© ­®¬Ґа ⮬ : 6017-2A0B

 ‘®¤Ґа¦Ё¬®Ґ Ї ЇЄЁ C:\Users\kiss\Documents\Xpdf\aebru_2014_all

06.02.2015  17:39    <DIR>          .
06.02.2015  17:39    <DIR>          ..
06.02.2015  17:27           419я818 eng_car-sales-in-april-2014.pdf
06.02.2015  17:26           523я622 eng_car-sales-in-august-2014.pdf
06.02.2015  17:24           611я574 eng_car-sales-in-december-2014.pdf
06.02.2015  17:27           526я186 eng_car-sales-in-july-2014.pdf
06.02.2015  17:27           510я101 eng_car-sales-in-june-2014.pdf
06.02.2015  17:27           415я731 eng_car-sales-in-may-2014.pdf
06.02.2015  17:24           606я111 eng_car-sales-in-november-2014.pdf
06.02.2015  17:25           529я078 eng_car-sales-in-october-2014.pdf
06.02.2015  17:25           533я419 eng_car-sales-in-september-2014.pdf
06.02.2015  17:29           617я946 sales-in-december_2013_eng_final.pdf
06.02.2015  17:28           484я429 sales-in-february_2014_eng_final.pdf
06.02.2015  17:28           390я069 sales-in-january_2014_eng_final_1.pdf
06.02.2015  17:28           488я489 sales-in-march_2014_eng_final.pdf
              13 д ©«®ў      6я656я573 Ў ©в
               2 Ї Ї®Є  389я802я004я480 Ў ©в бў®Ў®¤­®

Вот такой должна быть команда для конвертера

In []:
pdftotext [options] [PDF-file [text-file]]
In [10]:
!"C:\Program Files\Xpdf\bin64\pdftotext.exe" -table C:\Users\kiss\Documents\Xpdf\aebru_2014_all\eng_car-sales-in-april-2014.pdf C:\Users\kiss\Documents\Xpdf\aebru_2014_all_txt\eng_car-sales-in-april-2014.txt
In [6]:
!chcp 65001
Active code page: 65001

In [15]:
import subprocess
In [24]:
pdftotext=r'"C:\Program Files\Xpdf\bin64\pdftotext.exe" -table C:\Users\kiss\Documents\Xpdf\aebru_2014_all\eng_car-sales-in-april-2014.pdf C:\Users\kiss\Documents\Xpdf\aebru_2014_all_txt\eng_car-sales-in-april-2014.txt'
In [14]:
help('print')
#r'C:\Users\kiss\Documents\Xpdf\aebru_2014_all_txt\eng_car-sales-in-april-2014.txt.
no documentation found for 'print'


In [25]:
myProcess = subprocess.Popen(
    pdftotext, 
    shell=True,
    stdout = subprocess.PIPE,
    stderr = subprocess.PIPE)
In [26]:
out, error = myProcess.communicate()
In [27]:
out, error
Out[27]:
('', '')
In [28]:
pdftostdout=r'"C:\Program Files\Xpdf\bin64\pdftotext.exe" -table C:\Users\kiss\Documents\Xpdf\aebru_2014_all\eng_car-sales-in-april-2014.pdf stdout'
In [30]:
myProcess = subprocess.Popen(
    pdftostdout, 
    shell=True,
    stdout = subprocess.PIPE,
    stderr = subprocess.PIPE)
out, error = myProcess.communicate()
out, error
Out[30]:
('', '')
In []:
2. Код для парсинга трех таблиц []()

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

In []:
# Первая - самые продаваемые марки (25 строк)
#Lada 151527 159490 -5% 44100 50102 -12%
#Renault* 67208 57217 17% 19178 17914 7%
#
with open('C:\\Users\\kiss\\Documents\\Xpdf\\AEB_2014_4.txt') as f1:
    for line in f1:
        if len(line.split())== 7:                   # number of columns
            if line.split()[6].find('%') != -1:     # last column like 7% (include '%')
                if line.split()[0] != 'Total':      # Filter out first row with column names
                    print ' '.join(line.split())    # Delimiter of columns is Spase, convert list to string  
In []:
# Вторая - суммарные продажи по фирмам (25 строк)
#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%
#
with open('C:\\Users\\kiss\\Documents\\Xpdf\\AEB_2014_4.txt') as f2:
    for line in f2:
        if len(line.split())== 11:
            if line.split()[10].find('%') != -1:
                if line.split()[3].isalnum():
                    print ' '.join(line.split())
In []:
list3=[] # We can write resuls to list of lists, instead of list of strings
In []:
#Третья должна состоять  из 25 строк вида:
#1 Granta Lada 52765 26674 98% 15596 9798 59%
#2 Solaris Hyundai 35941 38051 -6% 10553 10979 -4%
#
with open('C:\\Users\\kiss\\Documents\\Xpdf\\AEB_2014_4.txt') as f3:
    for line in f3:
        if len(line.split())== 9:
            if line.split()[8].find('%') != -1:
                if line.split()[0].isalnum():
                    print ' '.join(line.split())
                    l3.append(line.split())         # To form list of lists
In []:
out = open('C:\\Users\\kiss\\Documents\\Xpdf\\AEB_2014_4_tab3.csv', 'w')
for row in l3:
    for column in row:
        out.write('"%s",' % column)
    out.write('\n')
out.close()
In []:
# First two rows
"1","Granta","Lada","52765","26674","98%","15596","9798","59%",
"2","Solaris","Hyundai","35941","38051","-6%","10553","10979","-4%",
In [31]:
import os
In [32]:
os.path
Out[32]:
<module 'ntpath' from 'C:\Users\kiss\Anaconda\lib\ntpath.pyc'>
In [33]:
import sys
In [34]:
sys.path
Out[34]:
['',
 'C:\\Users\\kiss\\Documents\\Python-Django',
 'C:\\Users\\kiss\\Anaconda\\Lib\\site-packages\\django\\bin',
 'C:\\Users\\kiss\\Anaconda\\python27.zip',
 'C:\\Users\\kiss\\Anaconda\\DLLs',
 'C:\\Users\\kiss\\Anaconda\\lib',
 'C:\\Users\\kiss\\Anaconda\\lib\\plat-win',
 'C:\\Users\\kiss\\Anaconda\\lib\\lib-tk',
 'C:\\Users\\kiss\\Anaconda',
 'C:\\Users\\kiss\\Anaconda\\lib\\site-packages',
 'C:\\Users\\kiss\\Anaconda\\lib\\site-packages\\PIL',
 'C:\\Users\\kiss\\Anaconda\\lib\\site-packages\\Sphinx-1.2.3-py2.7.egg',
 'C:\\Users\\kiss\\Anaconda\\lib\\site-packages\\win32',
 'C:\\Users\\kiss\\Anaconda\\lib\\site-packages\\win32\\lib',
 'C:\\Users\\kiss\\Anaconda\\lib\\site-packages\\Pythonwin',
 'C:\\Users\\kiss\\Anaconda\\lib\\site-packages\\queuelib-1.2.2-py2.7.egg',
 'C:\\Users\\kiss\\Anaconda\\lib\\site-packages\\runipy-0.1.1-py2.7.egg',
 'C:\\Users\\kiss\\Anaconda\\lib\\site-packages\\setuptools-11.3.1-py2.7.egg',
 'C:\\Users\\kiss\\Anaconda\\lib\\site-packages\\IPython\\extensions']
In [35]:
sys.path.append('C:\\Users\\kiss\\SkyDrive\\Docs\\pdftotext\\AEB\\pdgtotext')
In [36]:
sys.path
Out[36]:
['',
 'C:\\Users\\kiss\\Documents\\Python-Django',
 'C:\\Users\\kiss\\Anaconda\\Lib\\site-packages\\django\\bin',
 'C:\\Users\\kiss\\Anaconda\\python27.zip',
 'C:\\Users\\kiss\\Anaconda\\DLLs',
 'C:\\Users\\kiss\\Anaconda\\lib',
 'C:\\Users\\kiss\\Anaconda\\lib\\plat-win',
 'C:\\Users\\kiss\\Anaconda\\lib\\lib-tk',
 'C:\\Users\\kiss\\Anaconda',
 'C:\\Users\\kiss\\Anaconda\\lib\\site-packages',
 'C:\\Users\\kiss\\Anaconda\\lib\\site-packages\\PIL',
 'C:\\Users\\kiss\\Anaconda\\lib\\site-packages\\Sphinx-1.2.3-py2.7.egg',
 'C:\\Users\\kiss\\Anaconda\\lib\\site-packages\\win32',
 'C:\\Users\\kiss\\Anaconda\\lib\\site-packages\\win32\\lib',
 'C:\\Users\\kiss\\Anaconda\\lib\\site-packages\\Pythonwin',
 'C:\\Users\\kiss\\Anaconda\\lib\\site-packages\\queuelib-1.2.2-py2.7.egg',
 'C:\\Users\\kiss\\Anaconda\\lib\\site-packages\\runipy-0.1.1-py2.7.egg',
 'C:\\Users\\kiss\\Anaconda\\lib\\site-packages\\setuptools-11.3.1-py2.7.egg',
 'C:\\Users\\kiss\\Anaconda\\lib\\site-packages\\IPython\\extensions',
 'C:\\Users\\kiss\\SkyDrive\\Docs\\pdftotext\\AEB\\pdgtotext']
In [37]:
!dir C:\Users\kiss\SkyDrive\Docs\pdftotext\AEB\pdgtotext
 Volume in drive C has no label.
 Volume Serial Number is 6017-2A0B

 Directory of C:\Users\kiss\SkyDrive\Docs\pdftotext\AEB\pdgtotext

16.02.2015  19:13    <DIR>          .
16.02.2015  19:13    <DIR>          ..
16.02.2015  18:57             5В 721 aebto3tables.py
16.02.2015  19:13             5В 549 aebto3tables.pyc
15.02.2015  19:24               743 pdgtotext.nja
14.02.2015  15:29                 0 __init__.py
               4 File(s)         12В 013 bytes
               2 Dir(s)  389В 312В 315В 392 bytes free

In [38]:
import aebto3tables
> c:\users\kiss\skydrive\docs\pdftotext\aeb\pdgtotext\aebto3tables.py(37)Aebto3tables()
-> def allpdffromdir(self, path=PDFDATAFOLDER, targetpath=TXTDATAFOLDER):
(Pdb) 
(Pdb) 
(Pdb) 
(Pdb)  path=PDFDATAFOLDER, targetpath=TXTDATAFOLDER
*** ValueError: too many values to unpack
(Pdb) path=PDFDATAFOLDER
(Pdb) targetpath=TXTDATAFOLDER
(Pdb) l
 32          ->3 (tab3)
 33       """
 34   
 35       import pdb; pdb.set_trace()
 36   
 37  ->     def allpdffromdir(self, path=PDFDATAFOLDER, targetpath=TXTDATAFOLDER):
 38           """
 39           The loop into folder with preliminary saved pdf files
 40           Warning: it does not work if filename include additional
 41           dots ('.') except file extension '.pdf'
 42           """
(Pdb) q

---------------------------------------------------------------------------
BdbQuit                                   Traceback (most recent call last)
<ipython-input-38-e531332d618c> in <module>()
----> 1 import aebto3tables

C:\Users\kiss\SkyDrive\Docs\pdftotext\AEB\pdgtotext\aebto3tables.py in <module>()
     21 
     22 
---> 23 class Aebto3tables:
     24     def __init__(self, label):
     25         self.label = label

C:\Users\kiss\SkyDrive\Docs\pdftotext\AEB\pdgtotext\aebto3tables.py in Aebto3tables()
     35     import pdb; pdb.set_trace()
     36 
---> 37     def allpdffromdir(self, path=PDFDATAFOLDER, targetpath=TXTDATAFOLDER):
     38         """
     39         The loop into folder with preliminary saved pdf files

C:\Users\kiss\SkyDrive\Docs\pdftotext\AEB\pdgtotext\aebto3tables.py in Aebto3tables()
     35     import pdb; pdb.set_trace()
     36 
---> 37     def allpdffromdir(self, path=PDFDATAFOLDER, targetpath=TXTDATAFOLDER):
     38         """
     39         The loop into folder with preliminary saved pdf files

C:\Users\kiss\Anaconda\lib\bdb.pyc in trace_dispatch(self, frame, event, arg)
     47             return # None
     48         if event == 'line':
---> 49             return self.dispatch_line(frame)
     50         if event == 'call':
     51             return self.dispatch_call(frame, arg)

C:\Users\kiss\Anaconda\lib\bdb.pyc in dispatch_line(self, frame)
     66         if self.stop_here(frame) or self.break_here(frame):
     67             self.user_line(frame)
---> 68             if self.quitting: raise BdbQuit
     69         return self.trace_dispatch
     70 

BdbQuit: 
In [39]:
aebto3tables.OPTIONS
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-39-966d5689c5b9> in <module>()
----> 1 aebto3tables.OPTIONS

NameError: name 'aebto3tables' is not defined


Посты чуть ниже также могут вас заинтересовать

Комментариев нет:

Отправить комментарий