Я добавляю код для этого: он отлично работает для меня:
# This works in python 3
# required python packages
# tabula-py==1.0.0
# PyPDF2==1.26.0
# Pillow==4.0.0
# pdfminer.six==20170720
import os
import shutil
import warnings
from io import StringIO
import requests
import tabula
from PIL import Image
from PyPDF2 import PdfFileWriter, PdfFileReader
from pdfminer.converter import TextConverter
from pdfminer.layout import LAParams
from pdfminer.pdfinterp import PDFResourceManager, PDFPageInterpreter
from pdfminer.pdfpage import PDFPage
warnings.filterwarnings("ignore")
def download_file(url):
local_filename = url.split('/')[-1]
local_filename = local_filename.replace("%20", "_")
r = requests.get(url, stream=True)
print(r)
with open(local_filename, 'wb') as f:
shutil.copyfileobj(r.raw, f)
return local_filename
class PDFExtractor():
def __init__(self, url):
self.url = url
# Downloading File in local
def break_pdf(self, filename, start_page=-1, end_page=-1):
pdf_reader = PdfFileReader(open(filename, "rb"))
# Reading each pdf one by one
total_pages = pdf_reader.numPages
if start_page == -1:
start_page = 0
elif start_page < 1 or start_page > total_pages:
return "Start Page Selection Is Wrong"
else:
start_page = start_page - 1
if end_page == -1:
end_page = total_pages
elif end_page < 1 or end_page > total_pages - 1:
return "End Page Selection Is Wrong"
else:
end_page = end_page
for i in range(start_page, end_page):
output = PdfFileWriter()
output.addPage(pdf_reader.getPage(i))
with open(str(i + 1) + "_" + filename, "wb") as outputStream:
output.write(outputStream)
def extract_text_algo_1(self, file):
pdf_reader = PdfFileReader(open(file, 'rb'))
# creating a page object
pageObj = pdf_reader.getPage(0)
# extracting extract_text from page
text = pageObj.extractText()
text = text.replace("\n", "").replace("\t", "")
return text
def extract_text_algo_2(self, file):
pdfResourceManager = PDFResourceManager()
retstr = StringIO()
la_params = LAParams()
device = TextConverter(pdfResourceManager, retstr, codec='utf-8', laparams=la_params)
fp = open(file, 'rb')
interpreter = PDFPageInterpreter(pdfResourceManager, device)
password = ""
max_pages = 0
caching = True
page_num = set()
for page in PDFPage.get_pages(fp, page_num, maxpages=max_pages, password=password, caching=caching,
check_extractable=True):
interpreter.process_page(page)
text = retstr.getvalue()
text = text.replace("\t", "").replace("\n", "")
fp.close()
device.close()
retstr.close()
return text
def extract_text(self, file):
text1 = self.extract_text_algo_1(file)
text2 = self.extract_text_algo_2(file)
if len(text2) > len(str(text1)):
return text2
else:
return text1
def extarct_table(self, file):
# Read pdf into DataFrame
try:
df = tabula.read_pdf(file, output_format="csv")
except:
print("Error Reading Table")
return
print("\nPrinting Table Content: \n", df)
print("\nDone Printing Table Content\n")
def tiff_header_for_CCITT(self, width, height, img_size, CCITT_group=4):
tiff_header_struct = '<' + '2s' + 'h' + 'l' + 'h' + 'hhll' * 8 + 'h'
return struct.pack(tiff_header_struct,
b'II', # Byte order indication: Little indian
42, # Version number (always 42)
8, # Offset to first IFD
8, # Number of tags in IFD
256, 4, 1, width, # ImageWidth, LONG, 1, width
257, 4, 1, height, # ImageLength, LONG, 1, lenght
258, 3, 1, 1, # BitsPerSample, SHORT, 1, 1
259, 3, 1, CCITT_group, # Compression, SHORT, 1, 4 = CCITT Group 4 fax encoding
262, 3, 1, 0, # Threshholding, SHORT, 1, 0 = WhiteIsZero
273, 4, 1, struct.calcsize(tiff_header_struct), # StripOffsets, LONG, 1, len of header
278, 4, 1, height, # RowsPerStrip, LONG, 1, lenght
279, 4, 1, img_size, # StripByteCounts, LONG, 1, size of extract_image
0 # last IFD
)
def extract_image(self, filename):
number = 1
pdf_reader = PdfFileReader(open(filename, 'rb'))
for i in range(0, pdf_reader.numPages):
page = pdf_reader.getPage(i)
try:
xObject = page['/Resources']['/XObject'].getObject()
except:
print("No XObject Found")
return
for obj in xObject:
try:
if xObject[obj]['/Subtype'] == '/Image':
size = (xObject[obj]['/Width'], xObject[obj]['/Height'])
data = xObject[obj]._data
if xObject[obj]['/ColorSpace'] == '/DeviceRGB':
mode = "RGB"
else:
mode = "P"
image_name = filename.split(".")[0] + str(number)
print(xObject[obj]['/Filter'])
if xObject[obj]['/Filter'] == '/FlateDecode':
data = xObject[obj].getData()
img = Image.frombytes(mode, size, data)
img.save(image_name + "_Flate.png")
# save_to_s3(imagename + "_Flate.png")
print("Image_Saved")
number += 1
elif xObject[obj]['/Filter'] == '/DCTDecode':
img = open(image_name + "_DCT.jpg", "wb")
img.write(data)
# save_to_s3(imagename + "_DCT.jpg")
img.close()
number += 1
elif xObject[obj]['/Filter'] == '/JPXDecode':
img = open(image_name + "_JPX.jp2", "wb")
img.write(data)
# save_to_s3(imagename + "_JPX.jp2")
img.close()
number += 1
elif xObject[obj]['/Filter'] == '/CCITTFaxDecode':
if xObject[obj]['/DecodeParms']['/K'] == -1:
CCITT_group = 4
else:
CCITT_group = 3
width = xObject[obj]['/Width']
height = xObject[obj]['/Height']
data = xObject[obj]._data # sorry, getData() does not work for CCITTFaxDecode
img_size = len(data)
tiff_header = self.tiff_header_for_CCITT(width, height, img_size, CCITT_group)
img_name = image_name + '_CCITT.tiff'
with open(img_name, 'wb') as img_file:
img_file.write(tiff_header + data)
# save_to_s3(img_name)
number += 1
except:
continue
return number
def read_pages(self, start_page=-1, end_page=-1):
# Downloading file locally
downloaded_file = download_file(self.url)
print(downloaded_file)
# breaking PDF into number of pages in diff pdf files
self.break_pdf(downloaded_file, start_page, end_page)
# creating a pdf reader object
pdf_reader = PdfFileReader(open(downloaded_file, 'rb'))
# Reading each pdf one by one
total_pages = pdf_reader.numPages
if start_page == -1:
start_page = 0
elif start_page < 1 or start_page > total_pages:
return "Start Page Selection Is Wrong"
else:
start_page = start_page - 1
if end_page == -1:
end_page = total_pages
elif end_page < 1 or end_page > total_pages - 1:
return "End Page Selection Is Wrong"
else:
end_page = end_page
for i in range(start_page, end_page):
# creating a page based filename
file = str(i + 1) + "_" + downloaded_file
print("\nStarting to Read Page: ", i + 1, "\n -----------===-------------")
file_text = self.extract_text(file)
print(file_text)
self.extract_image(file)
self.extarct_table(file)
os.remove(file)
print("Stopped Reading Page: ", i + 1, "\n -----------===-------------")
os.remove(downloaded_file)
# I have tested on these 3 pdf files
# url = "http://s3.amazonaws.com/NLP_Project/Original_Documents/Healthcare-January-2017.pdf"
url = "http://s3.amazonaws.com/NLP_Project/Original_Documents/Sample_Test.pdf"
# url = "http://s3.amazonaws.com/NLP_Project/Original_Documents/Sazerac_FS_2017_06_30%20Annual.pdf"
# creating the instance of class
pdf_extractor = PDFExtractor(url)
# Getting desired data out
pdf_extractor.read_pages(15, 23)
Без оптимизации компилятор производит очень немой код - каждая команда компилируется очень простым способом, так, чтобы это сделало намеченную вещь. Сборкам Отладки отключили оптимизацию по умолчанию, потому что без оптимизации произведенный исполняемый файл соответствует исходному коду простым способом.
, Как только Вы включаете оптимизацию, компилятор применяет много различных методов для создания кода выполненным быстрее, все еще делая то же самое. Наиболее заметным отличием между оптимизированными и неоптимизированными сборками в Visual C++ является факт, которым значения переменных сохранены в регистрах максимально долго в оптимизированных сборках, в то время как без оптимизации они всегда хранятся в память. Это влияет не только на скорость кода, но и она также влияет на отладку. В результате этой оптимизации отладчик не может надежно получить значение переменной, когда Вы ступаете через код.
существует несколько другой оптимизации, примененной компилятором, как описано в /O Опции (Оптимизируйте Код), документы MSDN . Поскольку общее описание различных методов оптимизации видит статья .
Wikipedia Compiler OptimizationОт Paul Vick блог:
Это удаляет любые инструкции по NOP, что мы иначе испустили бы для помощи в отладке. Когда оптимизация выключена (и отладочная информация включена), компилятор испустит инструкции по NOP для строк, которые не имеют никакого фактического IL связанным с ними, но которые Вы могли бы хотеть поставить точку останова. Наиболее распространенным примером чего-то вроде этого был бы “End If“ оператора “If” - нет никакого фактического IL, испускаемого для Конца, Если, таким образом, мы не испускаем NOP, отладчик не позволит Вам установить точку останова на нем. Включение оптимизации вынуждает компилятор не испустить NOPs.
Мы делаем простой анализ базисного блока сгенерированного IL для удаления любых блоков мертвого кода. Таким образом, мы разбиваем каждый метод на блоки IL, разделенного командами перехода. Путем выполнения быстрого анализа того, как блоки находятся во взаимосвязи, мы можем определить любые блоки, которые не имеют никаких ответвлений в них. Таким образом мы можем выяснить блоки кода, которые никогда не будут выполняться и могут быть опущены, делая блок немного меньшим. Мы также делаем некоторую незначительную оптимизацию ответвления в этой точке также - например, если Вы GoTo другой Оператор перехода, мы просто оптимизируем первый GoTo для перехода к цели второго GoTo.
Мы испускаем DebuggableAttribute с набором IsJITOptimizerDisabled ко Лжи. В основном это позволяет JIT во время выполнения оптимизировать код, как это считает целесообразным, включая переупорядочение и встраивание кода. Это произведет более эффективный и меньший код, но это означает, что попытка отладить код может быть очень сложной (как любой, кто попробовал его, скажет Вам). Фактический список того, что оптимизация JIT, является чем-то, что я не знаю - возможно, кто-то как Chris Brumme вмешается в какой-то момент на этом. Длинное и за исключением него - то, что переключатель оптимизации включает оптимизацию, которая могла бы сделать точки останова установки и продвижение через Ваш код тяжелее.
Короткий ответ: используйте - Вол и позвольте компилятору сделать свое задание.
длинный ответ: эффект другого вида оптимизации невозможно предсказать точно. Иногда оптимизация для быстрого кода на самом деле приведет к меньшему коду, оптимизируя для размера. Если Вы действительно хотите получить последние 0,01% производительности (speedwise или sizewise), необходимо сравнить различной комбинации опций.
кроме того, последние версии Visual Studio имеют опции для более усовершенствованной оптимизации, такой как разовая ссылкой оптимизация и ведомая профилем оптимизация.