隐藏机器人的电子邮件地址 - 保留邮件地址:

Posted

技术标签:

【中文标题】隐藏机器人的电子邮件地址 - 保留邮件地址:【英文标题】:Hide Email Address from Bots - Keep mailto: 【发布时间】:2017-05-10 04:40:42 【问题描述】:

tl;博士

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


总结

使用脚本或联系表格混淆电子邮件

电子邮件地址需要对人类查看者完全可见维护mailto:功能

电子邮件地址不得为图片格式

电子邮件地址必须对垃圾邮件爬虫和垃圾邮件机器人“完全”隐藏任何其他类型的收割机


想要的效果:

没有脚本,拜托。项目中没有使用脚本,我想保持这种方式

电子邮件地址要么显示在页面上,要么可以在某种用户交互后轻松显示,例如打开模式。

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

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

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

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

我没有一个充满垃圾邮件的收件箱


有什么作用

添加联系表格 - 或类似的 - 而不是电子邮件地址

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

用地址的图像替换地址

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

它还删除 mailto: 功能,除非您使图像可点击,然后将mailto: 功能添加为链接的href,但这无法达到目的 现在该电子邮件对机器人可见。


什么可能有效:

pseudo-elementsCSS中的巧妙用法

使用base64 编码的解决方案

分解电子邮件地址并将各个部分分散到整个文档中,然后在用户单击按钮时将它们重新组合在一起(这可能涉及多个 CSS 类和anchor tags的用法)

通过CSS 更改html 属性

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

What if We Could Use CSS to Alter HTML Attributes?

其他超出我知识范围的创造性解决方案。


类似问题/修复

javascript: Protect your email address by Joe Maller

(这是 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>

Looking for a php only email address obfuscator function

(一个巧妙的解决方案,使用PHPCSS 首先reverse 使用 PHP 的电子邮件,然后 reverse 它 使用 CSS)一个非常有前途的解决方案伟大的!但这太容易解决了

Is it worth obfuscating email addresses on the web these days?

(Javascript 修复)

Best way to obfuscate an e-mail address on a website?

所选答案有效。它实际上工作得很好。它涉及将电子邮件编码为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>

Does e-mail address obfuscation actually work?

(这个超级用户问题的选择答案很棒,它展示了使用不同混淆方法接收的垃圾邮件数量的研究。

似乎使用CSS 操作电子邮件地址以使其成为rtl 确实有效。这与我在本节中链接的第一个问题中使用的方法相同。

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

SO 上还有很多其他问题都有类似的答案。我没有找到任何符合我想要的效果


问题:

是否可以通过结合两个或多个修复程序(甚至添加新修复程序)提高上述电子邮件混淆方法的效率(即尽可能少的垃圾邮件) 同时:

A- 维护mailto: 功能;和

B- 支持屏幕阅读器


编辑:

下面的许多答案和 cmets 提出了一个非常好的问题,同时表明如果没有某种 js 就不可能做到这一点

提出/暗示的问题是:

为什么不使用js

答案是我对js过敏

尽管开玩笑,

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

联系表格作为替代品越来越被接受 提供电子邮件地址 - 他们不应该这样做。

如果它可以在没有脚本的情况下完成,那么它应该在没有脚本的情况下完成 脚本。

好奇心:(事实上我目前正在使用js 修复程序之一)我想看看讨论这个问题是否会带来更好的做事方式它。

【问题讨论】:

我认为,如果您希望维护 mailto: 功能并且您不愿意使用 Javascript,那么这是不可能的。 你想使用 CSS 来改变 HTML 属性吗? @Rishav 我同意你的观点,如果不使用 js 来获得想要的效果可能会很棘手;但是,我会说,诸如我强调的将电子邮件编码为 html 实体的方法的存在可能会否定它的不可能性。 @MortezaAsadi 你能发布一个你所说的答案的例子吗? 没有脚本就无法解决这个问题,避免它们的要求毫无意义。我有办法解决这个问题,但需要一个脚本。 【参考方案1】:

您的请求的问题特别是“支持屏幕阅读器”,因为根据定义,屏幕阅读器是某种“机器人”。如果屏幕阅读器需要能够解释电子邮件地址,那么页面爬虫也能够解释它。

此外,mailto 属性的意义在于成为如何在网络上处理电子邮件地址的标准。询问是否有第二种方法可以做到这一点,就像询问是否有第二种标准。

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

老实说,只需获得一个带有一半像样垃圾邮件过滤器的电子邮件服务,并指定一个易于在收件箱中排序的默认主题行。

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

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

【讨论】:

与机器人战斗很糟糕,但总有一天我们会赢得战争......或者灭绝 抱歉,当机器人工作时,它会找到所有带有@ 的字符串,然后用? 拆分此文本并检查第一部分是否与正则表达式匹配。最后保存2个版本 不确定您的意思。我添加主题行的目的是希望最终用户不会更改它。这样,您可以创建一个电子邮件过滤器,将所有这些主题特定的电子邮件放入特定的文件夹中。重点不是防止机器人,而是帮助电子邮件规则。正如我之前所说,防止机器人是一场永无止境的战斗。 感谢您的连贯而详细的回答。当您说屏幕阅读器本质上是机器人时,我认为您提出了一个有效的观点。然而,这个想法是隐藏电子邮件,直到用户采取某种行动,如按下按钮打开模式。一旦发生用户交互,就会显示电子邮件地址。如果这可以在不使用脚本的情况下实现,那么这就是我的问题的答案。我给这个答案+1,因为你在电子邮件中添加主题行然后根据它过滤消息的方法是纯粹的天才。 “这个想法是隐藏电子邮件,直到用户采取某种操作,例如按下按钮打开模式”。如果该用户操作没有更改 DOM(这是屏幕阅读器实际阅读的内容),那么屏幕阅读器仍然能够看到它。由于用户操作而更改 DOM 的最佳方法是通过 JavaScript。网页是松散的 MVC 模式,其中 HTML、CSS 和 JavaScript 分别类似于模型、视图和控制器。这意味着任何修改都真正通过 JavaScript 进行,而在其他地方进行修改有点困难甚至是不可能的。【参考方案2】:

编写刮板的人希望使他们的刮板尽可能高效。因此,他们不会下载样式、脚本和其他外部资源。我知道没有使用 CSS 设置 mailto 链接的方法。另外,你特别说你不想使用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 的大小与其内容的大小相匹配,因此我们能做的最好的事情就是为其提供预定义的尺寸。

【讨论】:

我同意你的第一段,但你关于 iframe 内容的第二段是不正确的。机器人想要尽可能多的 HTML 内容。他们将下载 iframe 的内容,因为他们正在寻找链接、文本等。机器人不关心它是否是 iframe 标签。他们只会抓取页面。如果 URL 在 iframe 或 javascript 标记的 src 部分中,则会被抓取。【参考方案3】:

击败电子邮件机器人是一项艰巨的任务。您可能想查看***上的Email Address Harvesting countermeasures section。

我的背景故事是我编写了一个搜索机器人。它在多年前首次运行期间抓取了 105,000 多个 URL。我从中学到的是,网络爬虫从字面上看到 EVERYTHING 是文本,它出现在网页上。机器人会读取除图像之外的所有内容。

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

    使用 mailto: 标签时,CSS 和 JS 无关紧要。机器人专门针对“mailto:”关键字查看 HTML 页面。从冒号到下一个单引号或双引号(以先到者为准)的所有内容都被视为电子邮件地址。 HTML 实体电子邮件地址(如上面的示例)可以使用反向 ASCII 方法/函数快速翻译。运行上面的 JavaScript 代码 sn-p,快速将以下开头的字符串: your... 变成... "yourname@domain.com"。 (我的搜索机器人丢弃了带有 mailto:email 地址的 href,因为我想要网页的 URL 而不是电子邮件地址。)

    如果某个页面使机器人崩溃,机器人作者将调整机器人以修复该页面的崩溃,以便机器人将来不会再次在该页面崩溃。从而使他们的机器人更智能。

    机器人作者可以编写机器人,生成所有已知的电子邮件地址变体......无需抓取页面,也从不使用任何初始电子邮件地址。虽然这样做可能不可行,但对于当今的高核数 CPU(超线程并以 4+ GHz 运行)以及使用分布式云计算甚至超级计算机的可用性,这并非不可想象。可以想象,现在有人可以创建一个机器人农场来向每个人发送垃圾邮件,而无需知道任何人的电子邮件地址。 20 年前,那是不可理解的。

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

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

我认为在使用传统电子邮件服务器、不使用电子邮件服务器上的过滤器以及可能使用图像的情况下,不可能 100% 阻止垃圾邮件。

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

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

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

您已经创建了一个非常好的开始了解传统电子邮件的问题!向你致敬!

一个好的屏幕阅读器是来自Freedom Scientific 的JAWS。我以前用它来听听盲人用户如何阅读我的网页。 (如果您听到男性声音同时阅读动作 [如单击链接] 和文本,请尝试将 1 个声音更改为女性声音,以便 1 个声音阅读动作,另一个阅读文本。这样更容易听到如何阅读网页视力障碍者。)

祝您Email Address Harvesting countermeasure 的努力好运!

【讨论】:

非常感谢您非常彻底的回答。您分享了丰富的信息。这些信息有助于进一步解决问题,并可能最终找到解决问题的方法。 不客气!很高兴帮助您获得额外的经验见解。我很欣赏这个奖项。这是一个惊喜。谢谢!【参考方案4】:

首先,我认为用 CSS 做任何事情都行不通。所有机器人(除了 Google 的爬虫)都会忽略网站上的所有样式。任何解决方案都必须使用 JS 或服务器端。

服务器端解决方案可能是创建一个链接到新选项卡的&lt;a&gt;,该选项卡只是重定向到所需的mailto

这就是我现在的所有想法。希望对您有所帮助。

【讨论】:

当我大约一年前测试它时,所有主要浏览器都支持它,我可以看到将 mailto: 处理为 302 重定向中的位置因为“安全”原因而消失,就像你已经不能再拥有file:s。 (话虽如此,当禁用 javascript 时,我们使用此重定向作为后备。) 确实如此。好想法【参考方案5】:

这是一种使用 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 属性。 (您链接的article 是一种“天上掉馅饼”的沉思,与今天或不久的将来可能发生的事情没有任何关系。)

您提到的 HTML 实体方法,或它的一些变体,可能是最简单的选项,但会产生一些效果。此外,iframe approach 很聪明,server redirect approach 非常棒。但是,这三个都容易受到机器人的攻击:

HTML 实体只需为 converted(检测很简单) iframe 引用的文档might simply be followed 也可以简单地遵循服务器重定向

通过上述方法,在 data-contact 属性中使用 base64 编码的电子邮件地址是非常“一次性”的——只要 scraper 不是专门为您的网站设计的,它应该可以工作。

【讨论】:

我喜欢这个。如果他们没有启用 js,他们可以去给其他人发邮件。【参考方案6】:

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

这里回答的一些基于脚本的选项可能适用于某些机器人,但您想要无脚本,所以,不,您不能。

【讨论】:

他们可以对电子邮件使用某种加密,并在 JavaScript 中动态解密。即使是简单的 +1 密码也可以解决问题。理论上可以破解,但没有机器人会破解它。【参考方案7】:

简单 + 大量 @ + 无需工具即可编辑

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

【讨论】:

我喜欢这个,整洁的小sn-p! 喜欢这个小东西,@AndyHolmes 我为此使用了 onclick="...",也适用于移动设备(在 android / mobile chrome 上测试),不知道这样会不会变得更没用,因为机器人可能会比 onmouseover 更多地检查 onclick。 @goleon onclick 可以在移动设备上使用,onmouseover 不能,因为移动设备没有悬停状态【参考方案8】:

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

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

虽然传统上,recaptcha 不仅对屏幕阅读器而且对人类来说都很难,但您可以阅读 google 的 nocaptcha recaptcha 的作用 here 因为它们与可访问性测试有关。它似乎对屏幕阅读器显示了承诺,因为它从他们的视图中呈现为传统的复选框。

示例 #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,然后返回电子邮件,否则机器人可以简单地在代码中获取它。

示例 #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'; 

【讨论】:

如果您对使用谷歌产品有不好的感觉,您可以使用与hCaptcha 或多或少相同的功能。【参考方案9】:

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

&lt;a href="mailto:myemail@ignore-domain.com"&gt;myemail@&lt;span style="display:none;"&gt;ignore-&lt;/span&gt;domain.com

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

到目前为止,这种方法对我来说非常有效。你可以阅读更多关于这个 - http://techblog.tilllate.com/2008/07/20/ten-methods-to-obfuscate-e-mail-addresses-compared/

【讨论】:

很抱歉,但这种方法不是一个好方法,因为大多数(如果不是所有)好的机器人都在锚文本和 a href 内查找。使用 display:none 不会成功。【参考方案10】:

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>

附:要求:用户必须启用 JavaScript

【讨论】:

【参考方案11】:

基于 MaanooAk 的代码,这是我的版本:

<a href="mailto: Mike Myers"
onclick="this.href=this.href.replace(' Mike ','MikeMy'); this.href=this.href.replace('Myers','ers@vwx.yz')">&#9993; Send Email</a>

与 MaanookAks 版本的不同之处在于,悬停时您看不到 mailto: 和损坏的电子邮件地址,但 mailto: 和联系人姓名。当你点击它时,名称会被电子邮件地址替换。

在代码中,电子邮件地址分为两部分。电子邮件地址在代码中的任何地方都不完整。

【讨论】:

有人建议我将代码“Mike”更改为“%20Mike%20”。但在我的浏览器中,这只有在我还将“mailto:Mike Myers”更改为“mailto:%20Mike%20Myers”时才有效。不知道是不是真的有必要把这里所有的空格都改成%20。 不幸的是,一些浏览器在 onclick 之前执行 href,所以这不是一个好的解决方案。更好的解决方案是将电子邮件地址的更正和 mailto: 以正确的顺序放入一个函数中,例如通过“onclick”调用。我将发布此解决方案。【参考方案12】:

这是我的新解决方案。我首先通过添加小块来构建电子邮件地址字符串,然后将此字符串也用作标题:

adress = 'mailt' + 'o:MikeM' + 'yers@v' + 'wx.yz';
document.getElementsByClassName('Email')[0].title = adress;
function mail()window.location.href = adress;
&lt;a class='Email' onclick='mail()'&gt;&amp;#9993; Send Email&lt;/a&gt;

我在网站的页脚中使用它。许多页面的页脚都相同。

【讨论】:

以上是关于隐藏机器人的电子邮件地址 - 保留邮件地址:的主要内容,如果未能解决你的问题,请参考以下文章

检测过期的电子邮件地址? [复制]

隐藏或替换电子邮件地址 mailto:Laravel

现在值得在网络上混淆电子邮件地址吗?

如何在 C# 中屏蔽/隐藏电子邮件地址

在 WooCommerce 电子邮件通知中隐藏本地取货的送货地址

JavaScript 隐藏网页抓取工具的电子邮件地址