1

我正在尝试使用 rel="nofollow" 参数关闭所有外部网址:

我写了这个简单的中间件:

import re

NOFOLLOW_RE = re.compile(u'<a (?![^>]*rel=["\']nofollow[\'"])'\
                         u'(?![^>]*href=["\']mysite\.com[\'"])',
                         re.UNICODE|re.IGNORECASE)

class NofollowLinkMiddleware(object):

    def process_response(self, request, response):
        if ("text" in response['Content-Type']):

            response.content = re.sub(NOFOLLOW_RE, u'<a rel="nofollow" ', response.content.decode('UTF8') )
            return response
        else:
            return response

它可以工作,但会关闭所有内部和外部链接。而且我不知道如何添加 <noindex></noindex> 标记来链接。

4

2 回答 2

3

起初,您忘记了“http://”和 url 路径。所以,你的正则表达式应该是:

NOFOLLOW_RE = re.compile(u'<a (?![^>]*rel=["\']nofollow[\'"])'\
                         u'(?![^>]*href=["\']http://mysite\.com(/[^\'"]*)?[\'"])',
                         re.U|re.I)

然后,您还需要考虑以“/”和“#”开头的 href 作为内部链接:

NOFOLLOW_RE = re.compile(u'<a (?![^>]*rel=["\']nofollow[\'"])'\
                         u'(?![^>]*href=["\'](?:https?://mysite\.com(?:/[^\'"]*)|/[^\'"]*|#[^\'"]*)[\'"])',
                         re.U|re.I)

此外,您可能希望考虑 3 级域和“https://”协议。

对于 <noindex> 标签,您可以使用组,请查看Python 文档中的 re.sub()

NOFOLLOW_RE = re.compile(u'<a (?P<link>(?![^>]*rel=["\']nofollow[\'"])'\
                         u'(?![^>]*href=["\'](?:https?://mysite\.com(?:/[^\'"]*)|/[^\'"]*|#[^\'"]*)[\'"]).*?</a>)',
                         re.U|re.I)
...
response.content = NOFOLLOW_RE.sub(u'<noindex><a rel="nofollow" \g<link></noindex>', your_html)

这个正则表达式很古怪。我强烈建议您为它编写一个测试,使用 <a> 标记的所有可能组合以及您可以想象的属性。如果之后你在这段代码中发现了一些问题,测试将帮助你不要破坏一切。

于 2012-07-19T15:24:24.403 回答
1

我知道我很晚了,但我正在为其他人留下答案。@HighCat 对所有案例都给出了正确的答案,除了一个。上面的正则表达式还将nofollow添加到链接http://example.com

所以在这种情况下正则表达式应该是 =>

import re

NOFOLLOW_RE = re.compile(u'<a (?P<link>(?![^>]*rel=["\']nofollow[\'"])'\
                         u'(?![^>]*href=["\'](?:https?://example\.com/?(?:[^\'"]*)|/[^\'"]*|#[^\'"]*)[\'"]).*?</a>)',
                         re.U|re.I)

class NofollowLinkMiddleware(object):

    def process_response(self, request, response):
        if ("text" in response['Content-Type']):

            response.content = NOFOLLOW_RE.sub(u'<a rel="nofollow" target="_blank" \g<link>', response.content.decode('UTF8') )
            return response
        else:
            return response

这是微小的变化。我应该评论或编辑,但我没有足够的声誉(评论),编辑也需要 6+ 字符更改。

于 2015-10-25T21:38:11.273 回答