Ошибка ‘NoneType’ при попытке установить атрибуты для первого тега из проанализированного PDF-документа на Python с помощью BeautifulSoup4

#python #html #css #parsing #beautifulsoup

#python #HTML #css #синтаксический анализ #beautifulsoup

Вопрос:

Я пишу скрипт на Python с использованием pdfminer.six для преобразования огромного количества PDF-файлов в html, чтобы впоследствии загрузить их в электронный магазин. До сих пор основные текстовые блоки были проанализированы довольно хорошо, но в процессе мне пришлось заменить все интервалы на divs (и удалить интервалы из их атрибутов) по понятным причинам, так что теперь структура документа выглядит следующим образом:

 <div> #first main block
    <div>
        Product desc heading
    </div>
    <div>
        Product desc text
    </div>
    #etc etc
</div>

<div> #second main block
    <div>
        Product specs heading
    </div>
    <div>
        Product specs text
    </div>
    #etc etc
</div>
  

Проблема заключается в навигации в идентичных разделах. Если я попытаюсь найти самый первый div и добавить к нему некоторые атрибуты, как предлагают документы:

 firstdiv = soup.find('div')
firstdiv['class'] = 'main_productinfo'
  

Результат вполне предсказуем — IDLE выводит следующую ошибку:

 File "C:UsersblablaAppDataLocalProgramsPythonPython37libsite-packagesbs4element.py", line 1036, in __setitem__
    self.attrs[key] = value
TypeError: 'NoneType' object does not support item assignment

  

, поскольку find() метод не возвращает определенный результат (может быть найден, а может и не быть найден).

Я хочу преобразовать первый блок в каждом файле, а затем проанализировать таблицы (найденные в блоке спецификаций ниже) в html и объединить эти два в каждом загружаемом файле. Как я могу добавить атрибуты к первому тегу, не преобразовывая soup в string снова и снова (и, таким образом, делая его действительно, действительно уродливым, поскольку он преобразует недавно доработанный soup без каких-либо пробелов) и заменяя части строки в str(soup) ? Я совсем новичок в Python, и мне ничего не приходит в голову.

UPD: Я использую Python 3.7.2 на Win 7 64.

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

1. может ли не быть div?

2. @QHarr Дело в том, что есть div, он печатается просто отлично, но присвоение значения не работает, и найденный div обрабатывается так, как будто его там не было.

3. Я сделал то же самое, что и @chittown в моем удаленном ответе, и также получил назначение. Итак, я предполагаю, что с вашими фактическими данными работает что-то еще.

4. @QHarr Может быть, потому, что это в for цикле, который перебирает несколько файлов в каталоге, а не только один файл?

Ответ №1:

Я не получаю эту ошибку:

 import bs4

html = '''<div> #first main block
    <div>
        Product desc heading
    </div>
    <div>
        Product desc text
    </div>
    #etc etc
</div>

<div> #second main block
    <div>
        Product specs heading
    </div>
    <div>
        Product specs text
    </div>
    #etc etc
</div>'''

soup = bs4.BeautifulSoup(html, 'html.parser')

firstdiv = soup.find('div')
  

Вывод:

 print (firstdiv)
<div> #first main block
    <div>
        Product desc heading
    </div>
<div>
        Product desc text
    </div>
    #etc etc
</div>
  

Затем:

 firstdiv['class'] = 'main_productinfo'
print (firstdiv)

<div class="main_productinfo"> #first main block
    <div>
        Product desc heading
    </div>
<div>
        Product desc text
    </div>
    #etc etc
</div>
  

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

1. Ну, в этом-то и дело — firstdiv печатается нормально, но назначение у меня не работает.

2. как хранится исходный код html? другими словами, где находится часть вашего кода, которую вы сохранили soup ? Я вижу это выше, а не там, где вы его объявляете.

3. Он хранится в строковой переменной, куда отправляется исходный результат анализа из pdfminer. Затем эта переменная вводится в soup .

4. Используете ли вы ‘html.parser’? Или ‘lxml’?

5. Я использую html.parser .