PDFQuery: получить номер страницы, на которой находится элемент

Это первый раз, когда я использую PDFQuery для очистки PDF-файлов.

Что мне нужно сделать, так это получить цены из прайс-листа с несколькими страницами, я хочу передать код продукта в PDFQuery, и он должен найти код и вернуть цену рядом с ним. Проблема в том, что использование самого первого примера на странице Github позволяет получить местоположение текста, но в нем четко сказано: «Обратите внимание, что нам не нужно знать, где находится имя на странице или на какой странице оно находится». Это касается моего прайс-листа, но во всех других примерах указан номер страницы ( LTPage[pageid=1] ), но я не вижу, откуда мы берем номер страницы.

И если я не укажу номер страницы, он вернет ВСЕ тексты в одном и том же месте для ВСЕХ страниц.

Кроме того, я добавил функцию exactText, потому что коды могут быть, например, "92005", "92005C", "92005G", поэтому использование только :contains мало помогает.

Я попытался выбрать страницу, на которой находится элемент, и использовать JQuery .closest, но безуспешно.

Я проверил документацию PDFMiner и документация по PyQuery, но я не вижу ничего, что могло бы мне помочь =(

Мой код сейчас выглядит так:

import pdfquery

pdf = pdfquery.PDFQuery("tests/samples/priceList.pdf")
pdf.load()

code = "92005G"

def exactText():
    element = str(vars(this))
    text = str("u'" + code + "\\n'")
    if text in element:
        return True
    return False

#This should work if i could select the page where the element is located
#page = pdf.pq('LTPage:contains("'+code+'")')
#pageNum = page.attr('pageid')

#Here I would replace the "8" with the page number i get, or remove the LTPage 
#selector all together if i need to find the element first and then the page
label = pdf.pq('LTPage[page_index="8"] LTTextLineHorizontal:contains("'+code+'")').filter(exactText)

#Since we could use "JQuery selectors" i tried using ".closest", but it returns nothing
#page = label.closest('LTPage')
#pageNum = page.attr('pageid')

left_corner = float(label.attr('x0'))
bottom_corner = float(label.attr('y0'))

#Here I would replace the "8" with the page number i get
price = pdf.pq('LTPage[page_index="8"] LTTextLineHorizontal:in_bbox("%s, %s, %s, %s")' % (left_corner+110, bottom_corner, left_corner+140,     bottom_corner+20)).text()
print price

Любая помощь очень ценится, ребята и девушки!!!


person aampudia    schedule 07.05.2016    source источник


Ответы (2)


Может быть более элегантный способ, но я использовал для поиска страницы, на которой находится элемент, .interancestors('LTPage'). Пример кода ниже найдет все экземпляры «Мой текст» и сообщит вам, на какой странице он находится:

for pq in pdf.pq('LTTextLineHorizontal:contains("My Text")'):
    page_pq = pq.iterancestors('LTPage').next()   # Use just the first ancestor
    print 'Found the text "%s" on page %s' % ( pq.layout.get_text(), page_pq.layout.pageid)

Надеюсь, это поможет! :)

person albrnick    schedule 26.05.2016
comment
Привет!!! буду пробовать!!! я решил свою проблему с циклом, проходящим по всем страницам в PDF, поэтому я ищу первую страницу .... не нашел то, что искал ??? перейти на страницу 2 и так далее.... так что я всегда знаю, на какой странице я смотрю.... но я не уверен, есть ли проблема с производительностью... я пробовал с 200-страничным pdf и это сработало! большое спасибо за ваш ответ!! попробую и вернусь.... - person aampudia; 26.05.2016

Это должно работать в python3 (обратите внимание на вызов next(iterator) для получения первого предка страницы):

code = "92005G"

label = pdf.pq('LTPage:contains("{}")'.format(code))
page_pq = next(label.iterancestors('LTPage'))
pageNum = int(page_pq.layout.pageid)

label = pdf.pq('LTPage[page_index="{0}"] LTTextLineHorizontal:contains("{1}")'.format(pageNum, code)).filter(exactText)

left_corner = float(label.attr('x0'))
bottom_corner = float(label.attr('y0'))

price = pdf.pq('LTPage[page_index="{0}"] LTTextLineHorizontal:in_bbox("{1}, {2}, {3}, {4}")'.format(pageNum, left_corner+110, bottom_corner, left_corner+140, bottom_corner+20)).text()
person Benji    schedule 27.05.2020