Если утверждение основано на значении, существующем в файле jsonlines - PullRequest
1 голос
/ 27 сентября 2019

У меня есть код, который вытягивает более 400 PDF-файлов с веб-сайта через Beautiful Soup.PyPDF2 преобразует PDF-файлы в текст, который затем сохраняется в виде файла jsonlines с именем 'output.jsonl'.

Когда я сохраняю новые PDF-файлы в будущих обновлениях, я хочу, чтобы PyPDF преобразовывал только новые PDF-файлы в текст и добавлялфайл jsonlines с этим новым текстом, с которым я борюсь.

Файл jsonlines выглядит так:

{"id": "1234", "title": "Transcript", "url": "www.stackoverflow.com", "text": "200 pages worth of text"}
{"id": "1235", "title": "Transcript", "url": "www.stackoverflow.com", "text": "200 pages worth of text"}...

PDF-файлы называются «1234», «1235» и т. д.и сохраняются в file_path_PDFs.Я пытаюсь распознать, если это «id» является значением в файле jsonlines, тогда PyPDF2 не нужно преобразовывать его в текст.Если он не существует, обработайте его как обычно.

file_path_PDFs = 'C:/Users/.../PDFs/'
json_list = []

for filename in os.listdir(file_path_PDFs):   
    if os.path.exists('C:/Users/.../PDFs/output.jsonl'):
        with jsonlines.open('C:/Users/.../PDFs/output.jsonl') as reader:
            mytext = jsonlines.Reader.iter(reader)
            for obj in mytext:
                if filename[:-4] in mytext: #filename[:-4] removes .pdf from string
                    continue
                else:
                    ~convert to text~

with jsonlines.open('C:/Users/.../PDFs/output.jsonl', 'a') as writer:
    writer.write_all(json_list)

Как я полагаю, этот код не находит ни одно из значений и преобразует ВСЕ текст каждый раз, когда я его запускаю.Очевидно, что это довольно длительный процесс, каждый документ занимает 200 или 300 страниц.

1 Ответ

0 голосов
/ 27 сентября 2019

Обновления:

  • Оптимизировано для сохранения только поля id в DataFrame.
    • Был сохранен DataFrame (а не list), чтобы помочь в будущем расширении и гибкости.

Ответ:

ПослеПрорабатывая (что я считаю) ваш сценарий, у нас есть следующие настройки / требования:

  • У вас есть один файл jsonlines с именем output.jsonl.
  • Этот output.jsonl файлсодержит (n) словари;по одному на каждый PDF-файл, анализируемый PyPDF2.
  • Мы должны пройти через каталог из 400+ проанализированных PDF-файлов и определить, находится ли имя этого PDF-файла в output.jsonl.

Если этоправильно, давайте изменим тактику и выберем следующий подход:

  • Создать list имен файлов PDF (называемых pdfs).
  • Считать поле id из jsonlinesфайл (output.jsonl) в pandas.DataFrame (называемый df).
  • Перебрать список pdfs и проверить, находится ли имя файла (id) в кадре данных (df).
  • Если нет, добавьте имя файла в список (называемый notin).
  • Сделайте, как вы хотите, с помощью notin list, чтобы проанализировать эти новые файлы в ...как хотите.

Мой (расширенный) output.jsonl файл выглядит следующим образом:

{"id": "1234", "title": "Transcript", "url": "www.stackoverflow.com", "text": "200 pages worth of text"}
{"id": "1235", "title": "Transcript", "url": "www.stackoverflow.com", "text": "200 pages worth of text"}
{"id": "1236", "title": "Transcript", "url": "www.stackoverflow.com", "text": "200 pages worth of text"}
{"id": "1237", "title": "Transcript", "url": "www.stackoverflow.com", "text": "200 pages worth of text"}
{"id": "1238", "title": "Transcript", "url": "www.stackoverflow.com", "text": "200 pages worth of text"}

Вот код с комментариями для выполнения описанных выше шагов:

import os
import jsonlines
import pandas as pd

# Set the path to output.jsonl
path = os.path.expanduser('~/Desktop/output.jsonl')
# Build a list of PDFs (You'll use `os.listdir()`)
pdfs = ['1234.pdf', '1235.pdf', '1236.pdf', '1237.pdf', 
        '1238.pdf', '5000.pdf', '5001.pdf']
# Create an empty DataFrame.
df = pd.DataFrame()

# Read output.jsonl
with jsonlines.open(path) as reader:
    for line in reader.iter():
        # Add 'id' value to the DataFrame.
        df = df.append({'id': line.get('id')}, ignore_index=True)
# Display the DataFrame's contents.
print('Contents of the jsonlines file:\n')
print(df)

# Loop over the PDF filenames and test if each filename is in the DataFrame.
notin = [i for i in pdfs if os.path.splitext(i)[0] not in df['id'].values]
# Display the results.
print('\nThese PDFs are not in your jsonlines file:')
print(notin)    

Выход;обратите внимание, что файлы 5000.pdf и 5001.pdf не были найдены:

Contents of the jsonlines file:

     id
0  1234
1  1235
2  1236
3  1237
4  1238

These PDFs are not in your jsonlines file:
['5000.pdf', '5001.pdf']
...