首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在angular universal中检测网站页面中的网络爬虫

在angular universal中检测网站页面中的网络爬虫
EN

Stack Overflow用户
提问于 2019-10-22 21:23:45
回答 1查看 1.1K关注 0票数 1

我想要检测服务器端呈现的对我的页面的当前请求- ssr来自网络爬虫或普通用户。

我想在网络爬虫中做一些事情,而不是当它是用户的时候。

我想在网络爬虫访问页面以获取完整数据时运行ng-in-viewport

而不是在用户使用我的页面时运行。

如何检测这个东西?

EN

回答 1

Stack Overflow用户

发布于 2020-03-29 16:01:13

最近,我和你一样面临着同样的挑战。我为我的Angular应用程序设置了SSR,并且我使用StateTransfer,以避免在用户刚刚看到来自服务器的渲染内容后在浏览器中进行相同的API调用。

我有一个视图计数器,由于页面是在服务器端呈现的,我希望避免计算爬虫生成的视图。

所以,我的结论是:

server.ts (这是Angular SSR的标准生成文件)中,确保你从express传递的是请求对象,我的代码是这样的:

代码语言:javascript
复制
server.get('*', (req, res) => {
  res.render(indexHtml, {
    req, // Express request
    res, // Express response
    providers: [
      { provide: APP_BASE_HREF, useValue: req.baseUrl },
    ],
  });
});

然后,在您希望保留常量的任何constants.ts中,添加VIEWER注入令牌和可能的爬虫列表:

代码语言:javascript
复制
export const VIEWER = new InjectionToken<string>('viewer');
export const CRAWLER_AGENTS = [
  'googlebot', 'yandexbot', 'yahoo', 'bingbot',
  'baiduspider', 'facebookexternalhit', 'twitterbot', 'rogerbot',
  'linkedinbot', 'embedly', 'quora link preview', 'showyoubot', 'outbrain',
  'pinterest/0.', 'developers.google.com/+/web/snippet',
  'slackbot', 'vkshare', 'w3c_validator', 'redditbot', 'applebot',
  'whatsapp', 'flipboard', 'tumblr', 'bitlybot', 'skypeuripreview',
  'nuzzel', 'discordbot', 'google page speed'
];

然后,在我的app.module.ts中的providers中,我添加了新的provider,如果这是机器人或用户,它将包含信息:

代码语言:javascript
复制
import { NgModule, Optional, PLATFORM_ID } from '@angular/core';
import { isPlatformBrowser } from '@angular/common';
import { REQUEST } from '@nguniversal/express-engine/tokens';
import { CRAWLER_AGENTS, VIEWER } from './constants';

@NgModule({
  imports: [ /* ... */ ],
  declarations: [ /* ... */ ],
  providers: [
    {
      provide: VIEWER,
      useFactory: viewerFactory,
      deps: [PLATFORM_ID, [new Optional(), REQUEST]],
    },
  ],
})
export class AppModule {}

export function viewerFactory(platformId, req: Request): string {
  if (isPlatformBrowser(platformId)) {
    return 'user';
  }
  const userAgent = (req.get('user-agent') || '').toLowerCase();
  const isCrawler = CRAWLER_AGENTS.some(crawlerAgent => userAgent.indexOf(crawlerAgent) !== -1);
  return isCrawler ? 'bot' : 'user';
}

可以,根据Angular documentation,您可以将提供程序的依赖项作为数组传递。我们需要Optional来防止应用程序在客户端崩溃。显然,这里不存在Express request对象。

然后在你的页面组件中,你可以像这样检查查看器:

代码语言:javascript
复制
import { Component, Inject, Optional } from '@angular/core';

@Component({
  selector: 'app-article-page',
  templateUrl: './article-page.component.html',
  styleUrls: ['./article-page.component.scss'],
})
export class ArticlePageComponent {
  constructor(
    @Optional() @Inject(VIEWER) private viewer,
  ) {
    const countViews = this.viewer !== 'bot';
  }
}

如果你觉得我的回答有帮助,请别忘了把它标记为已接受。

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58505339

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档