从Bot隐藏电子邮件地址-保留mailto:


80

tl; dr

在不使用脚本的情况下从漫游器隐藏电子邮件地址并维护mailto:功能。方法还必须支持屏幕阅读器。


概要

  • 电子邮件混淆,无需使用脚本或联系表格

  • 电子邮件地址必须对观众完全可见,并保持mailto:功能

  • 电子邮件地址不能为图像形式

  • 电子邮件地址必须对垃圾邮件抓取者和垃圾邮件机器人以及任何其他收割者类型“完全”隐藏


所需效果:

  • 没有脚本。项目中没有使用脚本,我想保持这样

  • 电子邮件地址可以显示在页面上,也可以在用户进行某种形式的交互后轻松显示,例如打开模式。

  • 用户可以点击的电子邮件地址,这反过来会触发mailto:功能。

  • 单击电子邮件将打开用户的电子邮件应用程序。

    换句话说,mailto:功能必须起作用。

  • 电子邮件地址不可见或未标识为机器人的电子邮件地址(包括页面源)

  • 我的收件箱里没有垃圾邮件


什么工作

  • 添加联系表格-或类似内容-代替电子邮件地址

    我讨厌联络表格。我很少填写联系表格。如果没有电子邮件地址,我会寻找电话号码,如果没有电话号码,我会开始寻找替代服务。如果绝对需要,我只会填写联系表格。

  • 用地址图像替换地址

    这会对使用屏幕阅读器的人造成巨大的不利影响(请记住,您未来的项目中有视力障碍的人

    除非您使图像可单击,然后再将该功能添加为链接的,否则它还会删除mailto:功能,但这违背了目的,并且现在僵尸程序可以看到该电子邮件。mailto:href


可能有效的方法:

  • 巧妙地使用pseudo-elementsinCSS

  • 利用base64编码的解决方案

  • 分解电子邮件地址并在文档中散布各个部分,然后在用户单击按钮时将它们放回模态中(这可能涉及多个CSS类和的用法anchor tags

  • html通过更改属性CSS

    @MortezaAsadi在下面的评论中优雅地提出了可能性。这是完整链接-该文章来自2012年:

    如果我们可以使用CSS更改HTML属性怎么办?

  • 我所不了解的其他创造性解决方案。


类似的问题/修复

(这是乔·马勒(Joe Maller)提出的一个很好的解决方案,它可以很好地工作,但是它是基于脚本的

<SCRIPT TYPE="text/javascript">

  emailE = 'emailserver.com'

  emailE = ('yourname' + '@' + emailE)

  document.write('<A href="mailto:' + emailE + '">' + emailE + '</a>')

</script>



<NOSCRIPT>

  Email address protected by JavaScript

</NOSCRIPT>

  • 寻找一个PHP唯一的电子邮件地址混淆器功能

    (A聪明的解决方案同时使用PHP,并CSS于第一反向使用电子邮件,然后PHP扭转它与CSS回)一个非常有前景的解决方案,伟大的作品!但这太容易解决了

  • 这些天值得在Web上混淆电子邮件地址吗?

    (JavaScript修复)

  • 混淆网站上电子邮件地址的最佳方法?

    所选答案有效。实际上,它确实运作良好。它涉及将电子邮件编码为html entities。可以改善吗?

    这是它的样子;

    <A HREF="mailto:
    
    &#121;&#111;&#117;&#114;&#110;&#097;&#109;&#101;&#064;&#100;&#111;&#109;&#097;&#105;&#110;&#046;&#099;&#111;&#109;">
    
    &#121;&#111;&#117;&#114;&#110;&#097;&#109;&#101;&#064;&#100;&#111;&#109;&#097;&#105;&#110;&#046;&#099;&#111;&#109;
    
    </A>

  • 电子邮件地址混淆确实有效吗?

    (此超级用户问题的选定答案非常好,它提出了使用不同混淆方法接收的垃圾邮件数量的研究。

    似乎可以使用CSS来处理电子邮件地址rtl。这与本节中链接到的第一个问题所使用的方法相同。

    我不确定mailto:向修复程序添加功能会对结果产生什么影响。

  • 关于SO的其他问题也都有很多类似的答案。我没有找到适合我期望效果的任何东西


问题:

是否有可能以提高效率(即尽可能少的垃圾邮件越好)通过电子邮件混淆上面的方法将两个或更多的修复程序(甚至增加新的修补程序),而:

A-维护mailto:功能;和

B-支持的屏幕阅读器


编辑:

下面的许多答案和评论都提出了一个很好的问题,同时指出了在没有某种形式的情况下不可能做到这一点js

提出/提出的问题是:

为什么不使用js

答案是我对 js

虽然开玩笑

我问这个问题的三个主要原因是:

  • 联系表格已越来越被人们接受,以取代提供电子邮件地址的方式,但他们不应该这样做。

  • 如果可以不使用脚本就可以完成,那么应该不用脚本就可以完成

  • 好奇心:(因为我实际上正在使用其中一种js修复程序)我想看看讨论此事是否会导致更好的解决方法。


21
我认为,如果您希望维护mailto:功能并且不愿意使用Javascript,那么这是不可能的。
xrisk '16

是否要使用CSS更改HTML属性?
Morteza Asadi

@Rishav我同意您的观点,如果不使用js来获得预期的效果可能会非常棘手;但是,我要说的是,诸如我强调的那种将电子邮件编码为html实体的方法的存在可能会否定它的可能性。

@MortezaAsadi您可以张贴一个示例,称为答案吗?

@我爱-CSS来看看这篇文章:andydavies.me/blog/2012/08/13/...
莫尔塔扎·阿萨迪

Answers:


35

您的请求的问题特别是“支持屏幕阅读器”,因为按照定义,屏幕阅读器是某种“机器人”。如果屏幕阅读器需要能够解释该电子邮件地址,那么页面爬网程序也将能够对其进行解释。

同样,该mailto属性的要点是如何在网络上处理电子邮件地址的标准。询问是否存在第二种方法就是询问是否存在第二种标准。

通过脚本执行此操作与页面加载后仍然存在相同的问题,该脚本将已运行并在DOM中呈现电子邮件地址(除非您填充电子邮件地址on click或其他内容)。无论哪种方式,屏幕阅读器仍然会遇到问题,因为尚未加载。

老实说,只要获得一个带有垃圾邮件过滤器的电子邮件服务,并指定一个默认主题行,您就可以轻松地在收件箱中对其进行排序。

<a href="mailto:no-one@no-where.com?subject=Something to filter on">Email me</a>

您要问的是,该标准是否有两种方式来做某事,一种是针对机器人,另一种是针对非机器人。答案是没有,您必须尽可能地与机器人战斗。


8
它糟透了地与机器人作战,但是有一天我们将赢得战争……或灭绝
k2snowman69

抱歉,当机器人工作时,它会找到带有的所有字符串@,然后按分割此文本,?并检查第一部分是否与正则表达式匹配。最终保存2个版本
Adrian Bobrowski

不知道你的意思。我添加主题行的目的是希望最终用户不要更改它。这样,您可以创建电子邮件过滤器,以将所有这些主题特定的电子邮件放入特定的文件夹中。关键不是要防止漫游器,而是要辅助电子邮件规则。就像我之前说的,防止机器人漫游是一场永无止境的战斗。
k2snowman69 '16

感谢您提供连贯而详尽的答案。当您说屏幕阅读器本质上是机器人时,我认为您提出了一个正确的观点。但是,其想法是使电子邮件一直处于隐藏状态,直到用户采取某种操作(例如,按下按钮以打开模式)。一旦发生用户交互,便会显示电子邮件地址。如果不使用脚本就可以实现这一目标,那将是我的问题的答案。我给这个答案+1,因为您将主题行添加到电子邮件中,然后基于该主题过滤邮件的方法是纯粹的天才。

另外,关于mailto:属性,虽然确实有一点意义在于标准化电子邮件地址在网络上的显示方式-我不确定是否是这种情况-我更在乎,因为易于使用,您单击电子邮件地址。电子邮件客户端中会打开一条新消息,您只需键入并发送即可。最后,“标准”通常需要时间来赶上现实,而不是反过来。

29

击败电子邮件机器人是一个艰难的过程。您可能要查看Wikipedia上的“电子邮件地址收集”对策部分

我的背景故事是我写了一个搜索机器人。多年前的最初运行期间,它抓取了105,000+个URL。从我从中学到的知识来看,网络爬虫机器人从字面上看到了一切,即文字,出现在网页上。机器人会读取图像以外的所有内容。

由于以下原因,无法通过代码轻松阻止垃圾邮件:

  1. 使用mailto:标记时,CSS和JS无关紧要。漫游器专门查看HTML页面中的“ mailto:”关键字。从冒号到下一个单引号或双引号(以先到者为准)的所有内容都被视为电子邮件地址。可以使用反向ASCII方法/功能快速翻译HTML实体电子邮件地址(如上述示例)。运行上面的JavaScript代码段,可以将以&#121;&#111;&#117;&#114; ...开头的字符串快速转换为...“ yourname@domain.com”。(我的搜索机器人放弃了mailto:email地址的hrefs,因为我需要网页的URL,而不是电子邮件地址。)

  2. 如果某个页面使漫游器崩溃,则漫游器作者将在考虑该页面的情况下调整该漫游器以修复崩溃,从而以后该漫游器不会再次在该页面崩溃。从而使他们的机器人更智能。

  3. 机器人的作者可以编写机器人,该机器人生成电子邮件地址的所有已知变体...而无需爬网,并且从不使用任何入门电子邮件地址。尽管这样做可能不可行,但对于当今的高核数CPU(超线程并以4+ GHz运行),再加上使用基于云的分布式计算甚至是超级计算机的可用性,这并不是不可想象的。可以想象,现在有人可以创建一个机器人农场来向所有人发送垃圾邮件,而无需知道任何人的电子邮件地址。20年前,这简直令人难以理解。

  4. 免费电子邮件提供商有向其广告商出售免费用户帐户的历史。过去,只需注册一个免费的电子邮件帐户,即可自动为他们开绿灯,开始向该电子邮件地址发送垃圾邮件……而无需在线使用该电子邮件地址。我已经看到,以著名的公司名称多次发生。(我不会提及任何名字。)

  5. mailto:关键字是此IETF RFC的一部分,在该浏览器中,浏览器用于自动启动默认的电子邮件客户端,该客户端来自其中包含该关键字的链接。当发生JavaScript时,必须使用它来中断该应用程序的启动过程。

我认为使用传统电子邮件服务器时,如果不使用电子邮件服务器上的过滤器和图像,就不可能阻止100%的垃圾邮件。

有一种选择...您还可以构建一个类似于聊天的电子邮件客户端,该客户端在网站上内部运行。就像Facebook的聊天客户端一样。这是“有点像电子邮件”,但不是真正的电子邮件。它只是具有归档功能的一对一即时消息...登录后会自动加载。由于它具有文档附件+链接功能,因此它的工作原理类似于电子邮件...但没有垃圾邮件。只要您不构建外部可访问的API,那么它就是一个封闭的系统,人们无法向其中发送垃圾邮件。

如果您打算使用严格的传统电子邮件,那么最好的选择就是在公司的电子邮件服务器上运行Apache的SpamAssassin之类的东西。

您还可以尝试结合上面列出的多种策略,以使电子邮件收割者更难从网页中收集电子邮件地址。他们不会在100%的时间内阻止100%的垃圾邮件……同时还允许100%的屏幕阅读器为盲目的访客服务。

您已经很好地了解了传统电子邮件的问题!为此致以荣誉!

一个好的屏幕阅读器是JAWS自由科学。在听盲人如何阅读我的网页之前,我曾用过它。((如果您听到男性声音同时读了两个动作(例如单击链接)和文本,请尝试将一种声音改为女性,以便一种声音读入动作,另一种声音读入文本。这样可以更轻松地了解网页的阅读方式视障人士。)

祝您的电子邮件地址收集对策工作顺利!


2
非常感谢您的彻底答复。您分享了很多信息。这些信息有助于进一步解决该问题,并可能最终导致找出解决该问题的方法。

别客气!能够帮助您获得更多的经验性见解,是一种荣幸。我很感激这个奖项。这真是一个惊喜。谢谢你!
Clomp

25

这是一种确实使用JavaScript的方法,但是占用的空间很小。它也非常“贫民窟”,通常我不建议在HTML中使用内联JS的方法,除非您根本不愿使用JS。

<a
  href="#"
  data-contact="bGUtZW1haWxAdGhlLWRvbWFpbi5jb20="
  data-subj="QW4gQW1hemluZyBTdWJqZWN0"
  onfocus="this.href = 'mailto:' + atob(this.dataset.contact) + '?subject=' + atob(this.dataset.subj || '')"
  >
  Send an email
</a>

data-contact是base64编码的电子邮件地址。并且,data-subj是可选的base64编码主题。

在没有JS的情况下进行此操作的主要挑战是CSS无法更改HTML属性。(您链接的文章是“天上掉馅饼”的沉思,与现在或不久的将来没有任何关系。)

您提到的HTML实体方法或它的一些变体,可能是最简单的选择,将具有一定的功效。此外,该iframe方法很聪明,服务器重定向方法也很棒。但是,这三者都容易受到机器人的攻击:

使用上面概述的方法,在data-contact属性中使用base64编码的电子邮件地址是非常“一次性的”-只要抓取工具不是专门为您的站点设计的,它就可以工作。


我喜欢这个。如果他们没有启用js,则可以向其他人发送邮件。
迈克尔·罗杰斯

13

简单+很多@ +无需工具即可编辑

<a href="mailto:user@domain@@com"
   onmouseover="this.href=this.href.replace('@@','.')">
   Send email
</a>


我喜欢这个,简洁的小片段!
Marlon Creative

2
我喜欢@AndyHolmes这个小东西,我为此使用了onclick =“ ...”,它也可以在移动设备上运行(在android / mobile chrome上测试),不知道它是否会那样用处不大,因为机器人可能会检查onclick更多而不是一次鼠标悬停。
goleon

1
@goleon onclick可以在移动设备上运行,onmouseover则不会,因为移动电话没有悬停状态
Andy Holmes

7

您是否考虑过使用Google的Recaptcha Mailhide? https://www.google.com/recaptcha/admin#mailhide

其想法是,当用户单击复选框时(请参阅下面的nocaptcha),将显示完整的电子邮件地址。

虽然传统上recapcha不仅对屏幕阅读器很困难,而且对人类来说也很困难,但是Google nocaptcha recaptcha的作用并不突出,您可以在此处阅读 它们与可访问性测试有关的信息。从屏幕阅读器的角度来看,它似乎是一个传统的复选框,似乎对屏幕阅读器显示出了希望。 Nocaptcha reCAPTCHA

例1-不安全,但为便于说明

以下是一些示例代码,不使用mailhide,而是自己使用recaptcha来实现:https ://jsfiddle.net/43fad8pf/36/

<div class="container">
    <div id="recaptcha"></div>
</div>
<div id="email">
    Verify captcha to get e-mail
</div>

function createRecaptcha() {
    grecaptcha.render("recaptcha", {sitekey: "6LcgSAMTAAAAACc2C7rc6HB9ZmEX4SyB0bbAJvTG", theme: "light", callback: showEmail});
}
 createRecaptcha();

function showEmail() {
    // ideally you would do server side verification of the captcha and then the server would return the e-mail
  document.getElementById("email").innerHTML = "email@something.com";
}

注意:在我的示例中,我的电子邮件具有javascript函数。理想情况下,您将在服务器端对Recaptcha进行验证,然后返回电子邮件,否则bot可以简单地在代码中获取它。

Example#2-服务器端验证和电子邮件返回

如果我们使用更像这样的示例,则会获得额外的安全性:https : //designracy.com/recaptcha-using-ajax-php-and-jquery/

function showEmail() {
    /* Check if the captcha is complete */
    if ($("#g-recaptcha-response").val()) {
        $.ajax({
            type: ‘POST’,
            url: "verify.php", // The file we’re making the request to
            dataType: ‘html’,
            async: true,
            data: {
                captchaResponse: $("#g-recaptcha-response").val() // The generated response from the widget sent as a POST parameter
        },
        success: function (data) {
            alert("everything looks ok. Here is where we would take 'data' which contains the e-mail and put it somewhere in the document");
        },
        error: function (XMLHttpRequest, textStatus, errorThrown) {
            alert("You’re a bot");
        }
    });
} else {
    alert("Please fill the captcha!");
}
});

其中verify.php是:

$captcha = filter_input(INPUT_POST, ‘captchaResponse’); // get the captchaResponse parameter sent from our ajax

/* Check if captcha is filled */
if (!$captcha) {
    http_response_code(401); // Return error code if there is no captcha
}
$response =     file_get_contents("https://www.google.com/recaptcha/api/siteverify?secret=YOUR-SECRET-KEY-HERE&amp;amp;response=" . $captcha);
if ($response . success == false) {
echo ‘SPAM’;
http_response_code(401); // It’s SPAM! RETURN SOME KIND OF ERROR
} else {
// Everything is ok, should output this in json or something better, but this is an example
    echo 'email@something.com'; 
}

4

编写刮板的人希望使其刮板尽可能高效。因此,他们将不会下载样式,脚本和其他外部资源。我不知道mailto使用CSS设置链接的方法。此外,您曾明确表示不想使用Javascript设置链接。

如果您考虑还有其他类型的资源,那么还会有外部文档(即使用iframe的HTML文档)。几乎没有刮板会费心下载iframe的内容。因此,您可以简单地执行以下操作:

index.html:

<iframe src="frame.html" style="height: 1em; width: 100%; border: 0;"></iframe>

frame.html:

My email is <a href="mailto:me@example.com" target="_top">me@example.com</a>

对于人类用户而言,iframe看起来就像普通文本。默认情况下,iframe是内联透明的,因此我们只需要设置其边框和尺寸即可。如果不使用Javascript,就无法使iframe的大小与其内容的大小匹配,因此,我们能做的最好的事情就是为它提供预定义的尺寸。


3
我同意您的第一段,但是关于iframe内容的第二段是错误的。bot希望尽可能多的HTML内容。他们将下载iframe的内容,因为他们正在寻找链接,文本等。他们只会爬网页面。如果该网址位于iframe或javascript标记的src部分中,则会对其进行爬网。
Clomp

3

首先,我认为使用CSS进行任何操作均无效。所有漫游器(Google的爬虫除外)都只会忽略网站上的所有样式。任何解决方案都必须与JS或服务器端一起使用。

服务器端的解决方案可能是将<a>链接到新标签页,然后将其重定向到所需的标签mailto

这就是我目前的想法。希望能帮助到你。


1
大约一年前,当我对其进行测试时,所有主要的浏览器都支持它,但mailto:由于“安全”原因,我可能会认为302重定向中的某个位置已消失,就像您已经没有file:的那样。(也就是说,禁用javascript时,我们将此重定向用作备用。)
Ulrich Schwarz

确实如此。好的想法
Pablo Kvitca '16

2

满足您所有要求的简短答案是不可能

此处回答的一些基于脚本的选项可能对某些漫游器有效,但是您想要无脚本,因此,不,您不能。


他们可以对电子邮件使用某种加密,然后在JavaScript中对其进行动态解密。即使是简单的+1密码也可以解决问题。理论上很容易破解,但没有机器人能破解。
约翰ktejik

0

PHP解决方案

function printEmail($email){
    $email = '<a href="mailto:'.$email.'">'.$email.'</a>';
    $a = str_split($email);
    return "<script>document.write('".implode("'+'",$a)."');</script>";
}

使用

echo printEmail('test@gmail.com');

结果

<script>document.write('<'+'a'+' '+'h'+'r'+'e'+'f'+'='+'"'+'m'+'a'+'i'+'l'+'t'+'o'+':'+'t'+'e'+'s'+'t'+'@'+'g'+'m'+'a'+'i'+'l'+'.'+'c'+'o'+'m'+'"'+'>'+'t'+'e'+'s'+'t'+'@'+'g'+'m'+'a'+'i'+'l'+'.'+'c'+'o'+'m'+'<'+'/'+'a'+'>');</script>

PS要求:用户必须启用JavaScript


-3

我发现有效的一种方法是将其与CSS一起使用,如下所示:

<a href="mailto:myemail@ignore-domain.com">myemail@<span style="display:none;">ignore-</span>domain.com

然后编写一个JavaScript,用正则表达式ignoreme-href="mailto:..."属性中删除单词。这将从机器人中隐藏电子邮件,因为它将ignore-在真实域之前添加单词,并且可以在屏幕阅读器上使用,并且当用户单击链接时,自定义js函数ignore-将从href属性中删除单词,从而打开真实的电子邮件。

到目前为止,这种方法一直很有效。您可以在此阅读更多内容-http://techblog.tilllate.com/2008/07/20/ten-methods-to-obfuscate-e-mail-addresses-compared/


抱歉,此方法不是一个好方法,因为大多数(即使不是全部)好的bot也会在锚文本和a href。使用display:none并不会降低成本。
Simon Hayter
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.