lxml - 如何将img src更改为绝对链接

时间:2014-10-02 19:00:01

标签: python html python-2.7 lxml absolute-path

使用lxml,如何使用绝对链接全局替换所有src属性?

3 个答案:

答案 0 :(得分:6)

以下是一个示例代码,其中还包含<a href>

from lxml import etree, html
import urlparse

def fix_links(content, absolute_prefix):
    """
    Rewrite relative links to be absolute links based on certain URL.

    @param content: HTML snippet as a string
    """

    if type(content) == str:
        content = content.decode("utf-8")

    parser = etree.HTMLParser()

    content = content.strip()

    tree  = html.fragment_fromstring(content, create_parent=True)

    def join(base, url):
        """
        Join relative URL
        """
        if not (url.startswith("/") or "://" in url):
            return urlparse.urljoin(base, url)
        else:
            # Already absolute
            return url

    for node in tree.xpath('//*[@src]'):
        url = node.get('src')
        url = join(absolute_prefix, url)
        node.set('src', url)
    for node in tree.xpath('//*[@href]'):
        href = node.get('href')
        url = join(absolute_prefix, href)
        node.set('href', url)

    data =  etree.tostring(tree, pretty_print=False, encoding="utf-8")

    return data

The full story is available in Plone developer documentation

答案 1 :(得分:3)

我不确定何时添加它,但是从lxml.fromstring()创建的文档现在具有称为make_links_absolute的方法。来自documentation

  

make_links_absolute(base_href,resolve_base_href = True):

     

这使文档中的所有链接都是绝对的,并假设base_href是文档的URL。因此,如果您传递base_href =“ http://localhost/foo/bar.html”并且存在指向baz.html的链接,该链接将被重写为http://localhost/foo/baz.html

     

如果resolve_base_href为true,则将考虑任何标记(只需调用self.resolve_base_href())。

答案 2 :(得分:0)

在测试Mikko Ohtamaa的答案之后,这里有一些注意事项。 它适用于许多标签并使用lxm,有不同的情况,例如background-image:url(xxx)。所以我只用正则表达式代替。 这是解决方案,

content = re.sub('(?P<left>("|\'))\s*(?P<url>(\w|\.)+(/.+?)+)\s*(?P<right>("|\'))',
                     '\g<left>' + url[:url.rfind('/')] + '/\g<url>\g<right>', content)
content = re.sub('(?P<left>("|\'))\s*(?P<url>(/.+?)+)\s*(?P<right>("|\'))',
                     '\g<left>' + url[:url.find('/', 8)] + '\g<url>\g<right>', content)