Как мне сопоставить два списка и изменить только второй в каждой паре? - PullRequest
1 голос
/ 17 октября 2019

Я пытаюсь создать плагин Python для автоматизации добавления атрибутов HTML к гиперссылкам, которые соответствуют определенным критериям для сносок (в электронных книгах) - например, если это верхний индекс, если это число в квадратных или круглых скобках ... пока чтотак хорошо, и мне удалось добавить атрибуты, используя Beautiful Soup для этих условий.

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

Например:

// on chapter.xhtml

Footnote 1 <a id="fn1" href="../Text/chapter.xhtml#rfn1">[1]</a>
Footnote 2 <a id="fn2" href="../Text/chapter.xhtml#rfn2">[2]</a>

1. <a id="rfn1" href="../Text/chapter.xhtml#fn1">1.</a> Footnote 1
2. <a id="rfn2" href="../Text/chapter.xhtml#fn2">2.</a> Footnote 2

Желаемый результат - новозвратные ссылки могут появляться в любом месте книги, поэтому полезно автоматизировать этот процесс:


Footnote 1 <a id="fn1" href="../Text/chapter.xhtml#rfn1">[1]</a>
Footnote 2 <a id="fn2" href="../Text/chapter.xhtml#rfn2">[2]</a>

1. <a id="rfn1" href="../Text/chapter.xhtml#fn1" role="doc-backlink">1.</a> Footnote 1
2. <a id="rfn2" href="../Text/chapter.xhtml#fn2" role="doc-backlink">2.</a> Footnote 2

Теперь я хочу добавить атрибут HTML ко всем ссылкам, которые имеют функцию возврата к исходной ссылке. в паре. Это всегда будут ссылки в паре сносок, которые стоят на втором месте в книге (но их идентификатор можно назвать как угодно.) Однако есть много сносок, и я изо всех сил пытаюсь выполнить соответствующее упражнение.

Так чтоВот несколько вопросов, с которыми мне бы очень хотелось помочь:

Как найти идентификатор фрагмента каждой ссылки на сноску?

Как найти идентификатор каждой ссылки на сноску?

Как сравнить идентификаторы фрагментов и идентификаторы?

Как добавить атрибут HTML только ко второму вхождению в книге в каждой паре сносок?

Я пробовалвложенный в циклы, но я не совсем уверен, как этого добиться. В настоящее время я нахожу все ссылки, используя Beautiful Soup, и, если они удовлетворяют определенным критериям, добавляя соответствующие атрибуты, используя Beautiful Soup.

В электронных книгах есть несколько глав (файлы xhtml), поэтому я надеюсь, что этоне повлияет на результат работы плагина.

Я совершенно новичок в этом, так что спасибо за ваше время.

1 Ответ

0 голосов
/ 19 октября 2019

Предположение : сноски всегда идут вторыми.

Мы будем перебирать все ссылки на странице, пытаясь определить, содержит ли каждая ссылка идентификатор фрагмента в атрибуте href,Если это произойдет, мы будем использовать это для извлечения соответствующей ссылки.

Мы будем использовать find_next вместо find, потому что последний будет извлекать соответствующий тег из любого места в документе, тогда как find_next будет пытаться найти только с позиции обрабатываемого объекта. Я поясню это на примере:

some_link['href']
# ../Text/chapter.xhtml#rfn1

some_link.find('a', {'id': 'rfn1'})
# <a id="rfn1" href="../Text/chapter.xhtml#fn1" role="doc-backlink">1.</a>

Если мы используем find, мы не можем быть уверены, появилась ли найденная ссылка до исходной ссылки или после нее. Однако, если мы используем find_next ...

footnote_link = some_link.find_next('a', {'id': 'rfn1'})
footnote_link
# <a id="rfn1" href="../Text/chapter.xhtml#fn1" role="doc-backlink">1.</a>

footnote_link.find_next('a', {'id': 'fn1'})
# None

... мы можем быть уверены, что эта ссылка появилась второй (и, следовательно, сноска), потому что find_next вернет None, еслион не может найти совпадение, начиная с позиции объекта, на котором мы называем find_next.

Вот как, вероятно, будет выглядеть полный код:

for link in soup.find_all('a'):
    try:
        fragment_id = link['href'].rsplit('#', maxsplit=1)[1]
    except IndexError:
        # the `rsplit` returned only one string, meaning '#' wasn't found in the string
        continue

    footnote = link.find_next('a', {'id': fragment_id})
    if footnote:
        # a matching footnote has been found
        # you can add attributes to it by modifying `footnote`
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...