Làm cách nào để tạo PDF có thể tìm kiếm cho ứng dụng tìm kiếm bình?


8

Tôi đã làm nghiên cứu cho một dự án cá nhân rất quan trọng. Tôi muốn tạo Ứng dụng Tìm kiếm Flask cho phép tôi tìm kiếm nội dung trên 100 tệp PDF Plus. Tôi đã tìm thấy một số thông tin xung quanh A ElasticSearch Lib hoạt động tốt với bình.

#!/usr/bin/env python3
#-*- coding: utf-8 -*-

# import libraries to help read and create PDF
import PyPDF2
from fpdf import FPDF
import base64
import json
from flask import Flask, jsonify, request, render_template,  json
from datetime import datetime
import pandas as pd

# import the Elasticsearch low-level client library
from elasticsearch import Elasticsearch
# create a new client instance of Elasticsearch
elastic_client = Elasticsearch(hosts=["localhost"])
es = Elasticsearch("http://localhost:9200/")
app = Flask(__name__)

# create a new PDF object with FPDF
pdf = FPDF()

# use an iterator to create 10 pages
for page in range(10):
    pdf.add_page()
    pdf.set_font("Arial", size=14)
    pdf.cell(150, 12, txt="Object Rocket ROCKS!!", ln=1, align="C")

# output all of the data to a new PDF file
pdf.output("object_rocket.pdf")

'''
read_pdf = PyPDF2.PdfFileReader("object_rocket.pdf")
page = read_pdf.getPage(0)
page_mode = read_pdf.getPageMode()
page_text = page.extractText()
print (type(page_text))
'''
#with open(path, 'rb') as file:

# get the PDF path and read the file
file = "Sheet3.pdf"
read_pdf = PyPDF2.PdfFileReader(file, strict=False)
#print (read_pdf)

# get the read object's meta info
pdf_meta = read_pdf.getDocumentInfo()

# get the page numbers
num = read_pdf.getNumPages()
print ("PDF pages:", num)

# create a dictionary object for page data
all_pages = {}

# put meta data into a dict key
all_pages["meta"] = {}

# Use 'iteritems()` instead of 'items()' for Python 2
for meta, value in pdf_meta.items():
    print (meta, value)
    all_pages["meta"][meta] = value

# iterate the page numbers
for page in range(num):
    data = read_pdf.getPage(page)
    #page_mode = read_pdf.getPageMode()

    # extract the page's text
    page_text = data.extractText()

    # put the text data into the dict
    all_pages[page] = page_text

# create a JSON string from the dictionary
json_data = json.dumps(all_pages)
#print ("\nJSON:", json_data)

# convert JSON string to bytes-like obj
bytes_string = bytes(json_data, 'utf-8')
#print ("\nbytes_string:", bytes_string)

# convert bytes to base64 encoded string
encoded_pdf = base64.b64encode(bytes_string)
encoded_pdf = str(encoded_pdf)
#print ("\nbase64:", encoded_pdf)

# put the PDF data into a dictionary body to pass to the API request
body_doc = {"data": encoded_pdf}

# call the index() method to index the data
result = elastic_client.index(index="pdf", doc_type="_doc", id="42", body=body_doc)

# print the returned sresults
#print ("\nindex result:", result['result'])

# make another Elasticsearch API request to get the indexed PDF
result = elastic_client.get(index="pdf", doc_type='_doc', id=42)

# print the data to terminal
result_data = result["_source"]["data"]
#print ("\nresult_data:", result_data, '-- type:', type(result_data))

# decode the base64 data (use to [:] to slice off
# the 'b and ' in the string)
decoded_pdf = base64.b64decode(result_data[2:-1]).decode("utf-8")
#print ("\ndecoded_pdf:", decoded_pdf)

# take decoded string and make into JSON object
json_dict = json.loads(decoded_pdf)
#print ("\njson_str:", json_dict, "\n\ntype:", type(json_dict))
result2 = elastic_client.index(index="pdftext", doc_type="_doc", id="42", body=json_dict)

# create new FPDF object
pdf = FPDF()

# build the new PDF from the Elasticsearch dictionary
# Use 'iteritems()` instead of 'items()' for Python 2
""" for page, value in json_data:
    if page != "meta":
        # create new page
        pdf.add_page()
        pdf.set_font("Arial", size=14)

        # add content to page
        output = value + " -- Page: " + str(int(page)+1)
        pdf.cell(150, 12, txt=output, ln=1, align="C")
    else:
        # create the meta data for the new PDF
        for meta, meta_val in json_dict["meta"].items():
            if "title" in meta.lower():
                pdf.set_title(meta_val)
            elif "producer" in meta.lower() or "creator" in meta.lower():
                pdf.set_creator(meta_val)
 """
# output the PDF object's data to a PDF file
#pdf.output("object_rocket_from_elaticsearch.pdf" )

@app.route('/', methods=['GET'])
def index():

    return jsonify(json_dict)

@app.route('/<id>', methods=['GET'])
def index_by_id(id):

    return jsonify(json_dict[id])


""" @app.route('/insert_data', methods=['PUT'])
def insert_data():
    slug = request.form['slug']
    title = request.form['title']
    content = request.form['content']

    body = {
        'slug': slug,
        'title': title,
        'content': content,
        'timestamp': datetime.now()
    }

    result = es.index(index='contents', doc_type='title', id=slug, body=body)

    return jsonify(result) """



app.run(port=5003, debug=True)

------ Tiến trình ------ Bây giờ tôi có một giải pháp làm việc không có khả năng tìm kiếm ở mặt trước:

# Load_single_PDF_BY_PAGE_TO_index.py
  #!/usr/bin/env python3
#-*- coding: utf-8 -*-

# import libraries to help read and create PDF
import PyPDF2
from fpdf import FPDF
import base64

from flask import Flask, jsonify, request, render_template,  json
from datetime import datetime
import pandas as pd

# import the Elasticsearch low-level client library
from elasticsearch import Elasticsearch
# create a new client instance of Elasticsearch
elastic_client = Elasticsearch(hosts=["localhost"])
es = Elasticsearch("http://localhost:9200/")
app = Flask(__name__)


#with open(path, 'rb') as file:

# get the PDF path and read the file
file = "Sheet3.pdf"
read_pdf = PyPDF2.PdfFileReader(file, strict=False)
#print (read_pdf)

# get the read object's meta info
pdf_meta = read_pdf.getDocumentInfo()

# get the page numbers
num = read_pdf.getNumPages()
print ("PDF pages:", num)

# create a dictionary object for page data
all_pages = {}

# put meta data into a dict key
all_pages["meta"] = {}

# Use 'iteritems()` instead of 'items()' for Python 2
for meta, value in pdf_meta.items():
    print (meta, value)
    all_pages["meta"][meta] = value

x = 44
# iterate the page numbers
for page in range(num):
    data = read_pdf.getPage(page)
    #page_mode = read_pdf.getPageMode()

    # extract the page's text
    page_text = data.extractText()

    # put the text data into the dict
    all_pages[page] = page_text

    body_doc2 = {"data": page_text}
    result3 = elastic_client.index(index="pdfclearn", doc_type="_doc", id=x, body=body_doc2)
    x += 1

Các mã trên tải một pdf duy nhất vào elaticsearch theo trang.

from flask import Flask, jsonify, request,render_template
from elasticsearch import Elasticsearch
from datetime import datetime
es = Elasticsearch("http://localhost:9200/")

app = Flask(__name__)

@app.route('/pdf', methods=['GET'])
def index():
    results = es.get(index='pdfclearn', doc_type='_doc', id='44')
    return jsonify(results['_source'])


@app.route('/pdf/<id>', methods=['GET'])
def index_by_id(id):
    results = es.get(index='pdfclearn', doc_type='_doc', id=id)
    return jsonify(results['_source'])



@app.route('/search/<keyword>', methods=['POST','GET'])
def search(keyword):
    keyword = keyword

    body = {
        "query": {
            "multi_match": {
                "query": keyword,
                "fields": ["data"]
            }
        }
    }

    res = es.search(index="pdfclearn", doc_type="_doc", body=body)

    return jsonify(res['hits']['hits'])

@app.route("/searhbar")
def searhbar():
    return render_template("index.html")

@app.route("/searhbar/<string:box>")
def process(box):
    query = request.args.get('query')
    if box == 'names':
         keyword = box

    body = {
        "query": {
            "multi_match": {
                "query": keyword,
                "fields": ["data"]
            }
        }
    }

    res = es.search(index="pdfclearn", doc_type="_doc", body=body)

    return jsonify(res['hits']['hits'])

app.run(port=5003, debug=True)

Trong đoạn mã trên, chúng tôi có thể tìm kiếm trên tất cả các Trang cho một từ khóa hoặc cụm từ.

curl http://127.0.0.1:5003/search/test //it works!!

Tôi đã tìm thấy một blog về cách xử lý các tệp PDF dưới dạng chỉ mục Base64 trong ElasticSearch. Tôi đã thấy API của DocuSign làm điều này để tạo khuôn mẫu cho tài liệu. Tuy nhiên, tôi không hiểu Làm thế nào để Jsonify Base64 PDF theo cách có thể tìm kiếm cho Tìm kiếm đàn hồi.

curl "http://localhost:9200/pdftext/_doc/42"

curl -X POST "http://localhost:9200/pdf/_search?q=*"

Tôi có thể truy xuất Base64 của tài liệu 700 Trang. Nhưng tôi nghĩ điều tôi cần là lập chỉ mục và truy xuất từng trang của tài liệu.

Blog tôi đã nghiên cứu đã giúp tôi một phần:

tàn cuộc:

Tôi sẽ tiếp tục nghiên cứu Tìm kiếm đàn hồi và mã hóa và giải mã Base64. Nhưng tôi muốn một số trợ giúp để đạt được mục tiêu của tôi. Bất kỳ ví dụ chi tiết sẽ được nhiều đánh giá cao.


Đã tìm thấy một Lib cho Python, Whoosh: whoosh.readthedocs.io/en/latest/intro.html . Tôi sẽ thử một cách tiếp cận mới với lib này tiếp theo
BlackFox

Hiện đang thử nghiệm lib cho python, Scout: scout.readthedocs.io/en/latest/installation.html
BlackFox

Câu trả lời:


0

Vì vậy, tôi đã tìm thấy một lib gọi là trinh sát và ... làm cho nó hoạt động!

from scout_client import Scout

# import libraries to help read and create PDF

import PyPDF2
from fpdf import FPDF
import base64
import os
from flask import Flask, jsonify, request, render_template,  json

client = Scout('http://localhost:8000')

for k in range(7,18):
    read_pdf = PyPDF2.PdfFileReader("books/%s.pdf"%(k))
    num = read_pdf.getNumPages()
    print ("PDF pages:", num)
    all_pages = []
    for page in range(num):
        data = read_pdf.getPage(page) 
        page_text = data.extractText()  
        all_pages.append(page_text)

    import requests
    for z in all_pages:
        url = 'http://localhost:8000/documents/'
        data = {'content': z, 'indexes': ['test13']}
        headers = {
        'Content-Type': 'application/json',
        }

        response = requests.post(url, data=json.dumps(data), headers=headers)

    print(response)
  • Bây giờ tôi có thể lặp mặc dù nhiều PDF như tôi muốn tại địa phương
  • Đăng lên máy chủ để lập chỉ mục
  • và tìm kiếm từ khóa

Bây giờ tôi chỉ cần trợ giúp với Tạo giao diện cơ bản với thanh tìm kiếm gọi dữ liệu từ phản hồi JSON trong python và jar.


-1

Hãy thử điều này - https://www.elastic.co/guide/en/elaticsearch/reference/6.8/binary.html

sử dụng store=truecho kiểu dữ liệu này vì nó không lưu trữ dữ liệu cũng như không cho phép tìm kiếm theo mặc định.


Liên kết đến các tài liệu không hữu ích ở đây
BlackFox

Bạn đã thử phương pháp này?
Pankhuri Agarwal

Ya man ..... đó là điều đầu tiên tôi thử ....
BlackFox

Sự thành công? Sự thất bại? Thời gian đầu tư?
Pankhuri Agarwal

Liên kết đến các tài liệu không giúp tôi được ...
BlackFox
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.