6

有没有办法Controller从搜索引擎抓取中排除操作?是否有一个MVC动词(属性),可以在动作名称上方添加?

我想从搜索引擎抓取中排除以下 URL

Home/Secret?type=1

但我希望这可用于搜索引擎爬行

Home/Search
4

4 回答 4

10

我认为您需要动态生成 robots.txt 文件。

您应该创建一个 RobotController 来提供 robots.txt 文件。

在此处查看参考

与上述链接相关的是一个关于允许通过操作提供 .txt 扩展名的问题:https ://stackoverflow.com/a/14084127/511438

public ActionResult Robots()
{
    Response.ContentType = "text/plain";
    //-- Here you should write a response with the list of 
    //areas/controllers/action for search engines not to follow.
    return View();
}

添加一个 Robots.cshtml

映射路线,以便对文件的调用将改为调用上面的操作。

routes.MapRoute("Robots.txt",
                "robots.txt",
                new { controller = "Home", action = "Robots" });

这是 NoRobots 属性,其中包含用于获取具有该属性的区域/控制器/动作列表的代码。很抱歉解释完整的命名空间文本。希望有人能看到反射以更好地解决问题。

public sealed class NoRobotsAttribute : System.Attribute
{

    public static IEnumerable<MethodInfo> GetActions()
    {
        return Assembly.GetExecutingAssembly().GetTypes()
               .Where(t => (typeof(Controller).IsAssignableFrom(t)))
               .SelectMany(
                    type =>
                    type.GetMethods(BindingFlags.Public | BindingFlags.Instance)
                        .Where(a => a.ReturnType == typeof(ActionResult))
                 );

    }
    public static IEnumerable<Type> GetControllers()
    {
        return Assembly.GetExecutingAssembly().GetTypes()
               .Where(t => (typeof(Controller).IsAssignableFrom(t)));

    }


    public static List<string> GetNoRobots()
    {
        var robotList = new List<string>();

        foreach (var methodInfo in GetControllers().Where(w => w.DeclaringType != null))
        {
            var robotAttributes = methodInfo
                    .GetCustomAttributes(typeof(NoRobotsAttribute), false)
                    .Cast<NoRobotsAttribute>();

            foreach (var robotAttribute in robotAttributes)
            {
                 //-- run through any custom attributes on the norobots attribute. None currently specified.
            }
            List<string> namespaceSplit = methodInfo.DeclaringType.FullName.Split('.').ToList();

            var controllersIndex = namespaceSplit.IndexOf("Controllers");
            var controller = (controllersIndex > -1 ? "/" + namespaceSplit[controllersIndex + 1] : "");
            robotList.Add(controller);

        }

        foreach (var methodInfo in GetActions())
        {
            var robotAttributes = methodInfo
                    .GetCustomAttributes(typeof(NoRobotsAttribute), false)
                    .Cast<NoRobotsAttribute>();

            foreach (var robotAttribute in robotAttributes)
            {
                 //-- run through any custom attributes on the norobots attribute. None currently specified.
            }

            List<string> namespaceSplit = methodInfo.DeclaringType.FullName.Split('.').ToList();

            var areaIndex = namespaceSplit.IndexOf("Areas");
            var area = (areaIndex > -1 ? "/" + namespaceSplit[areaIndex + 1] : "");

            var controllersIndex = namespaceSplit.IndexOf("Controllers");
            var controller = (controllersIndex > -1 ? "/" + namespaceSplit[controllersIndex + 1] : "");

            var action = "/" + methodInfo.Name;

            robotList.Add(area + controller + action);

        }
        return robotList;
    }
}

用法:

[NoRobots] //Can be applied at controller or action method level.
public class HomeController : Controller
{
    [NoRobots]
    public ActionResult Index()
    {
        ViewData["Message"] = "Welcome to ASP.NET MVC!";
        List<string> x = NoRobotsAttribute.GetNoRobots();
        //-- Just some test code that wrote the result to a webpage.
        return View(x);
    }
}

...对于地区。

namespace MVC.Temp.Areas.MyArea.Controllers
{
    using MVC.Temp.Models.Home;

    [NoRobots]
    public class SubController : Controller
    {
        [NoRobots]
        public ActionResult SomeAction()
        {
            return View();
        }

    }
}

所以请记住,该解决方案依赖于命名空间,并且欢迎任何人可以提供的任何改进。

最后,您需要正确编写机器人文件,包括任何头信息和通配符支持。

于 2013-08-11T22:12:21.507 回答
2

如果它是可公开访问的,并且特别是在页面上链接,机器人可以/将会找到它。您可以rel="nofollow"在链接上使用,在页面本身上使用noindex 元标记,或使用 robots.txt 文件对Disallow页面进行索引。这将阻止所有诚实的搜索引擎(如谷歌、必应、雅虎)索引或跟踪链接,但不会阻止随机机器人查看页面。

尽管如此,该 URL 仍可供公众访问。人可以访问它,然后计算机可以。如果您想阻止公众访问它,您可能需要查看用户身份验证。

于 2013-08-11T21:40:27.207 回答
0

您想对搜索引擎隐藏它,还是可能没有人访问该 URL?因为任何请求您的 robots.txt 的人都会在其中找到 URL。

您不能只设置授权,只允许某些用户访问这些操作吗?当出现 HTTP 401 时,搜索引擎不会对其进行索引。

于 2013-08-12T06:31:14.793 回答
-1

可能您只需要更改路由。您可以添加以下路线。它将地址更改Home/Secret?type=1Home/Search

routes.MapRoute(
                name: "NewRoute",
                url: "{controller}/Search",
                defaults: new { controller = "Home", action = "Secret", type = UrlParameter.Optional }
            );

您也可以隐藏控制器名称:

routes.MapRoute(
                name: "NewRoute",
                url: "LadyGaga/Search",
                defaults: new { controller = "Home", action = "Secret", type = UrlParameter.Optional }
            );
于 2013-08-12T06:12:04.073 回答