如何匹配两个列表并只更改每对中的第二个?

2024-06-16 18:13:02 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在尝试制作一个Python插件来自动将HTML属性添加到满足脚注(在电子书中)特定条件的超链接中–例如,如果它是上标,如果它是方括号或圆括号中的数字…到目前为止还不错,我已经设法在这些条件下使用Beautiful Soup添加属性。你知道吗

在不同的电子书中有许多脚注对。电子书的制作方式都不同(例如,脚注不一定都有相同的类别)。每个脚注编号都有一个带有片段标识符的URL,该标识符双向链接到另一个带有相应ID的链接,以帮助读者导航。你知道吗

例如:

// 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属性,这些链接的任务是返回到该对中的初始链接。这些将永远是脚注对中的链接,在电子书中排名第二(但它们的标识符可以被命名为任何东西)。然而,有许多脚注,我正在努力做一个匹配的练习。你知道吗

因此,我非常感谢您的帮助:

如何找到每个脚注链接的片段标识符?你知道吗

如何找到每个脚注链接的ID?你知道吗

如何比较片段标识符和id?你知道吗

然后,如何在电子书的每个脚注对中只添加第二个出现的HTML属性?你知道吗

我尝试过嵌套for循环,但实际上我不确定如何实现这一点。目前,我正在查找所有使用Beautiful Soup的链接,如果它们满足某些条件,则使用Beautiful Soup添加相关属性。你知道吗

电子书中有多个章节(xhtml文件),所以我希望这不会影响插件的结果。你知道吗

我对这个完全陌生,所以谢谢你的时间。你知道吗


Tags: textid属性链接html标识符电子书chapter
1条回答
网友
1楼 · 发布于 2024-06-16 18:13:02

假设:脚注总是排在第二位。你知道吗

我们将遍历页面中的所有链接,尝试查看每个链接的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`

相关问题 更多 >