如何使用lxml和iterlinks替换链接

时间:2011-04-26 10:41:15

标签: python lxml

我是lxml的新手,我正在尝试使用iterlinks()来重写链接。

import lxml.html
html = lxml.html.document_fromstring(doc)
for element, attribute, link, pos in html.iterlinks():
    if attibute == "src":
         link = link.replace('foo', 'bar')
print lxml.html.tostring(html)

但是,这实际上并没有取代链接。我知道我可以使用.rewrite_links,但iterlinks提供了有关每个链接的更多信息,所以我更愿意使用它。

提前致谢。

4 个答案:

答案 0 :(得分:6)

您不必仅为变量名link分配新的(字符串)值,而是必须更改元素本身,在这种情况下,通过设置其src属性:

new_src = link.replace('foo', 'bar') # or element.get('src').replace('foo', 'bar')
element.set('src', new_src)

请注意 - 如果您知道自己感兴趣的“链接”,例如,只有img元素 - 您也可以使用.findall()(或xpath或css选择器)来获取元素使用.iterlinks()

答案 1 :(得分:1)

lxml提供了一个rewrite_links方法(或者将要解析的文本传递给文档的函数),以提供一种更改文档中所有链接的方法:

  

.rewrite_links(link_repl_func,resolve_base_href = True,base_href = None):   这将使用您给定的链接替换功能重写文档中的所有链接。如果您提供base_href值,则所有链接将在与此URL连接后传入。   对于每个链接,调用link_repl_func(link)。该函数然后返回新链接,或者无以删除包含该链接的属性或标记。请注意,所有链接都将被传入,包括“#anchor”(纯粹是内部)等链接,以及“mailto:bob@example.com”(或javascript:...)等链接。

答案 2 :(得分:0)

可能链接只是实际对象的副本。尝试替换循环中元素的属性。即使元素也只是一个副本,但它值得一试......

答案 3 :(得分:0)

这里是带有rewrite_links的工作代码:

from lxml.html import fromstring, tostring

e = fromstring("<html><body><a href='http://localhost'>hello</body></html>")

def my_rewriter(link):
  return "http://newlink.com"

e.rewrite_links(my_rewriter)
print(tostring(e))

输出:

    b'<html><body><a href="http://newlink.com">hello</a></body></html>'