查找每个引用并将其附加到html链接-Python

查找每个引用并将其附加到html链接-Python,python,html,regex,beautifulsoup,Python,Html,Regex,Beautifulsoup,我有一个从Wikipedia获得的HTML文件,希望找到页面上的每个链接,如/wiki/absithe,并将其替换为添加到前面的当前目录,如/home/fergus/wikiget/wiki/absithe,以便: 变成: <a href="/home/fergus/wikiget/wiki/Absinthe">Absinthe</a> 这贯穿整个文件 你有什么想法吗?我很乐意使用BeautifulSoup或Regex 您可以将函数与re.sub一起使用: def ma

我有一个从Wikipedia获得的HTML文件,希望找到页面上的每个链接,如/wiki/absithe,并将其替换为添加到前面的当前目录,如/home/fergus/wikiget/wiki/absithe,以便:

变成:

<a href="/home/fergus/wikiget/wiki/Absinthe">Absinthe</a>
这贯穿整个文件


你有什么想法吗?我很乐意使用BeautifulSoup或Regex

您可以将函数与re.sub一起使用:

def match(m):
    return '<a href="/home/fergus/wikiget' + m.group(1) + '">'

r = re.compile(r'<a\shref="([^"]+)">')
r.sub(match, yourtext)
例如:

>>> s = '<a href="/wiki/Absinthe">Absinthe</a>'
>>> r.sub(match, s)
'<a href="/home/fergus/wikiget/wiki/Absinthe">Absinthe</a>'

您可以将函数与re.sub一起使用:

def match(m):
    return '<a href="/home/fergus/wikiget' + m.group(1) + '">'

r = re.compile(r'<a\shref="([^"]+)">')
r.sub(match, yourtext)
例如:

>>> s = '<a href="/wiki/Absinthe">Absinthe</a>'
>>> r.sub(match, s)
'<a href="/home/fergus/wikiget/wiki/Absinthe">Absinthe</a>'

如果你真的只需要这么做,你可以用sed和它的-i选项来重写文件:

sed -e 's,href="/wiki,href="/home/fergus/wikiget/wiki,' wiki-file.html
然而,这里有一个使用可爱API的Python解决方案,以防您需要做更复杂的事情,或者您可能有格式错误的HTML等:

from lxml import etree
import re

parser = etree.HTMLParser()

with open("wiki-file.html") as fp:
    tree = etree.parse(fp, parser)

for e in tree.xpath("//a[@href]"):
    link = e.attrib['href']
    if re.search('^/wiki',link):
        e.attrib['href'] = '/home/fergus/wikiget'+link

# Or you can just specify the same filename to overwrite it:
with open("wiki-file-rewritten.html","w") as fp:
    fp.write(etree.tostring(tree))

请注意,对于目前的此类任务,lxml可能比BeautifulSoup更好,因为BeautifulSoup的作者给出了这个选项。

如果这是您真正需要做的,您可以使用sed和它的-i选项来重写文件:

sed -e 's,href="/wiki,href="/home/fergus/wikiget/wiki,' wiki-file.html
然而,这里有一个使用可爱API的Python解决方案,以防您需要做更复杂的事情,或者您可能有格式错误的HTML等:

from lxml import etree
import re

parser = etree.HTMLParser()

with open("wiki-file.html") as fp:
    tree = etree.parse(fp, parser)

for e in tree.xpath("//a[@href]"):
    link = e.attrib['href']
    if re.search('^/wiki',link):
        e.attrib['href'] = '/home/fergus/wikiget'+link

# Or you can just specify the same filename to overwrite it:
with open("wiki-file-rewritten.html","w") as fp:
    fp.write(etree.tostring(tree))
请注意,对于目前的此类任务,lxml可能比BeautifulSoup更好,这是BeautifulSoup的作者给出的解决方案。

这是使用re模块的解决方案:

这是另一个不使用re的:

这是使用re模块的解决方案:

这是另一个不使用re的:

我愿意

import re

ch = '<a href="/wiki/Absinthe">Absinthe</a>'

r = re.compile('(<a\s+href=")(/wiki/[^"]+">[^<]+</a>)')

print ch
print
print r.sub('\\1/home/fergus/wikiget\\2',ch)
编辑:

据说此解决方案不捕获具有附加属性的标记。我认为这是一个狭窄的字符串模式的目标,如

如果不是,那么,没问题,用更简单的RE编写解决方案很容易

r = re.compile('(<a\s+href="/)([^>]+">)')

ch = '<a href="/wiki/Aide:Homonymie" title="Aide:Homonymie">'
print ch
print r.sub('\\1home/fergus/wikiget/\\2',ch)
或者为什么不:

r = re.compile('(<a\s+href="/)')

ch = '<a href="/wiki/Aide:Homonymie" title="Aide:Homonymie">'
print ch
print r.sub('\\1home/fergus/wikiget/',ch)
我愿意

import re

ch = '<a href="/wiki/Absinthe">Absinthe</a>'

r = re.compile('(<a\s+href=")(/wiki/[^"]+">[^<]+</a>)')

print ch
print
print r.sub('\\1/home/fergus/wikiget\\2',ch)
编辑:

据说此解决方案不捕获具有附加属性的标记。我认为这是一个狭窄的字符串模式的目标,如

如果不是,那么,没问题,用更简单的RE编写解决方案很容易

r = re.compile('(<a\s+href="/)([^>]+">)')

ch = '<a href="/wiki/Aide:Homonymie" title="Aide:Homonymie">'
print ch
print r.sub('\\1home/fergus/wikiget/\\2',ch)
或者为什么不:

r = re.compile('(<a\s+href="/)')

ch = '<a href="/wiki/Aide:Homonymie" title="Aide:Homonymie">'
print ch
print r.sub('\\1home/fergus/wikiget/',ch)

如果您在linux中工作,那么有一个非常简单的解决方案来查找和替换文档中的文本。如果我得到了u-rite,那么请回复。如果您在linux中工作,那么有一个非常简单的解决方案来查找和替换文档中的文本。“如果我得到了你的祝福,请一定回答。”帕维尔·弗格斯·巴克。不连贯的代码:如果你在行上为行中的行进行迭代。。。这是因为文件太大,必须按行处理。但是readlines一次处理整个文件。所以它必须是针对open'file.html'或content=open'file.html'中的行,然后读出.writere.sub'href=/wiki/absithe','href=/home/fergus/wikiget/wiki/absithe',内容,但不是两者的混合。而且,做你所做的,替换就足够了!out.writecontent.replace'href=/wiki/absithe','href=/home/fergus/wikiget/wiki/absithe'@eyquem你是对的,不连贯,效率不高,但很简单,它可以工作。更新了我的评论以修复您报告的一些问题。@Fergus Barker,Pawel。不连贯的代码:如果你在行上为行中的行进行迭代。。。这是因为文件太大,必须按行处理。但是readlines一次处理整个文件。所以它必须是针对open'file.html'或content=open'file.html'中的行,然后读出.writere.sub'href=/wiki/absithe','href=/home/fergus/wikiget/wiki/absithe',内容,但不是两者的混合。而且,做你所做的,替换就足够了!out.writecontent.replace'href=/wiki/absithe','href=/home/fergus/wikiget/wiki/absithe'@eyquem你是对的,不连贯,效率不高,但很简单,它可以工作。更新了我的评论以解决您报告的一些问题。@J.F.塞巴斯蒂安如果这个词不是“苦艾酒”会变成什么?@eyquem:我已经替换了这个词以避免混淆。@J.F.塞巴斯蒂安它不能解决问题,您使用任何“词”的解决方案都不能是通用的。以网页为例。同一句话中有和。你将如何让“世界”成为法国,然后是酿酒,然后是伯格海姆,再然后是阿尔萨斯,再然后是葡萄酒?@J.F.塞巴斯蒂安此外,还有这样的链接:-或-@eyquem:1。与法国等的评论是错误的。代码使用的唯一条件是链接以“/”开头。2.如果您不想转换编辑链接,您可以在repl函数中使用link.startswith'/wiki'。@J.F.Sebastian如果这个词不是“苦艾酒”,它会变成什么?@eyquem:为了避免混淆,我已经替换了这个词。@J.F.Sebastian它不能解决问题,使用任何“词”的解决方案都不能是通用的。以网页为例。同一句话中有和。你将如何让“世界”成为法国,然后是酿酒,然后是伯格海姆,再然后是阿尔萨斯,再然后是葡萄酒?@J.F.塞巴斯蒂安此外,还有这样的链接:-或-@eyquem:1。与法国等的评论是错误的。代码使用的唯一条件是链接以“/”开头。2.如果你不想合作
nvert edit links您可以在repl函数中使用link.startswith'/wiki.+1:用于使用真正的解析器。rewrite_links是一个更简单的选择-1用于使用一个功能强大的工具,事实上,我没有否决,这是必要的useless@J.F.塞巴斯蒂安:谢谢你指出这一点——因为你已经用“重写”链接添加了答案,我将保留我的答案。@eyquem:谢谢你没有投反对票。我在回答中确实说过,如果你需要做更复杂的事情,或者你可能有格式不好的HTML,等等,我的经验经常证明是这样的。不过我同意你的观点。我没有对你使用lxml放置代码的条件给予足够的关注。有了这种调整,我同意你的看法:做简单的任务,使用简单的工具,如sed;对于更难的,使用解析器更好。如果XML/HTML的格式经常不正确,这将是一个真正的问题:它阻止了自信地使用正则表达式,而正则表达式非常强大,可以捕获非常复杂的模式。PS:我并不是真的在认真地谈论downvote:我认为我在Python方面的技能还不足以让比我优秀得多的程序员失望。这是一种强调我的观点+1的方式:使用真正的解析器。rewrite_links是一个更简单的选择-1用于使用一个功能强大的工具,事实上,我没有否决,这是必要的useless@J.F.塞巴斯蒂安:谢谢你指出这一点——因为你已经用“重写”链接添加了答案,我将保留我的答案。@eyquem:谢谢你没有投反对票。我在回答中确实说过,如果你需要做更复杂的事情,或者你可能有格式不好的HTML,等等,我的经验经常证明是这样的。不过我同意你的观点。我没有对你使用lxml放置代码的条件给予足够的关注。有了这种调整,我同意你的看法:做简单的任务,使用简单的工具,如sed;对于更难的,使用解析器更好。如果XML/HTML的格式经常不正确,这将是一个真正的问题:它阻止了自信地使用正则表达式,而正则表达式非常强大,可以捕获非常复杂的模式。PS:我并不是真的在认真地谈论downvote:我认为我在Python方面的技能还不足以让比我优秀得多的程序员失望。这是强调我观点的一种方式