Work the Shell - 人们如何在 Google 上找到您?

作者:Dave Taylor

我承认。上个月我跑题了,讲了如何使用一个简单的 shell 脚本函数将庞大而可怕的数字转换为更易读和可理解的值。跑题是因为我们当时正在研究 shell 脚本如何帮助您挖掘 Apache Web 服务器日志并提取有用且有趣的信息。

这次,我将展示如何确定人们用来找到您网站的最常用搜索词——只需调用几次 grep,也许还可以用几行 awk 来锦上添花。

了解 Google

为了使此方法有效,您的日志必须保存引荐来源信息,Apache 默认情况下会这样做。如果您查看您的 access_log 并看到如下行,您就会知道

195.110.84.91 - - [11/Oct/2006:04:04:19 -0600] "GET
↪/blog/images/rdf.png HTTP/1.0" 304 -
↪"http://www.askdavetaylor.com/date_math_in_linux_shell_script.html"
↪"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)"

虽然有点难读,但这是一个日志条目,记录了某人请求文件 /blog/images/rdf.png,并且引荐来源,即产生请求的页面,也显示为来自我的 askdavetaylor.com 网站的 date_math_in_linux_shell_script.html。

如果我们查看 HTML 命中的日志文件条目,我们会看到一个更有趣的引荐来源

81.208.53.251 - - [11/Oct/2006:07:32:32 -0600]
 ↪"GET /wicked/wicked-cool-shell-script-library.shtml
 ↪HTTP/1.1" 200 15656 "http://www.google.com/
↪search?q=Shell+Scripting+&hl=it&lr=&start=10&sa=N"
 ↪"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0;
 ↪.NET CLR 1.0.3705)"

也让我稍微解释一下。这里的请求是针对我网站 (intuitive.com) 上的 wicked-cool-shell-script-library.html,基于 Google 搜索(引荐来源是 google.com/search)。深入研究 Google 引荐来源条目中的参数,您可以看到搜索词是“Shell+Scripting”。回想一下,+ 在 URL 中表示空格,因此搜索实际上是“Shell Scripting”。

(奖励提示:因为我们位于 start=10,这意味着他们在结果的第二页上。因此,我们知道将此人引导到我网站的匹配项在 #11 和 #20 之间。)

好的,现在的问题是,我们能否仅提取这些搜索,并以某种方式分解它们,以便我们可以快速识别搜索词?当然可以!

提取 Google 搜索

现在,让我们只关注 Google 的搜索结果,但将其扩展到其他搜索引擎也很容易。幸运的是,它们都使用相同的基本 URL 结构

$ grep 'google.com/search' access_log | head -1
168.230.2.30 - - [11/Oct/2006:04:08:05 -0600]
 ↪"GET /coolweb/chap14.html HTTP/1.1" 200 31508
 ↪"http://www.google.com/search?q=%22important+Style+Sheet+
↪Attribute.%22&hl=en&lr=" "Mozilla/4.0 (compatible;
 ↪MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322;
 ↪.NET CLR 2.0.50727; InfoPath.1)"

好的,这很简单。现在,只需快速调用 awk 即可轻松提取引荐来源字段

$ grep 'google.com/search' access_log | head -1 | awk '{print $11}'
"http://www.google.com/search?q=%22important+Style+Sheet
↪+Attribute.%22&hl=en&lr="

好的,更进一步了。下一步是在 ? 处以及之后的 & 处截断值。有很多方法可以做到这一点,但我只使用两次 cut 调用,因为,嗯,这很容易

$ grep 'google.com/search' access_log | head -1 | awk
 ↪'{print $11}' | cut -d\? -f2 | cut -d\& -f1
q=%22important+Style+Sheet+Attribute.%22

太棒了!现在,我们需要从 Google 本身使用的 HTML 表单中剥离 q= artifact,将所有出现的 + 替换为空格,并将 %22 转换为双引号(一个小小的额外任务),以便搜索有意义。这可以使用 sed 完成

$ grep 'google.com/search' access_log | head -1 |
 ↪awk '{print $11}' | cut -d\? -f2 | cut
 ↪-d\& -f1 | sed 's/+/ /g;s/%22/"/g;s/q=//'
"important Style Sheet Attribute."

让我稍微解释一下,以便更容易看清发生了什么

grep 'google.com/search' access_log | \
  head -1 | \
  awk '{print $11}' | \
  cut -d\? -f2 | cut -d\& -f1 | \
  sed 's/+/ /g;s/%22/"/g;s/q=//'

显然,head -1 仅在调试时存在,因此当我们将其放入实际的 shell 脚本中时,我们将丢失该行。此外,让我们为访问日志的名称创建一个变量,以简化操作

#!/bin/sh

ACCESSLOG="/var/logs/httpd.logs/access_log"

grep 'google.com/search' $ACCESSLOG | \
  awk '{print $11}' | \
  cut -d\? -f2 | cut -d\& -f1 | \
  sed 's/+/ /g;s/%22/"/g;s/q=//'

我们快到了....

排序和整理

我在 Linux 中最喜欢的序列之一是sort | uniq -c | sort -rn,这将在本文中再次发挥作用。它有什么作用?它按字母顺序对输入进行排序,然后压缩重复的行,并在前缀计数中显示找到多少个匹配项。然后,它从最多匹配项到最少匹配项对结果进行排序。换句话说,它接受原始输入并将其转换为数字排序的摘要。

此序列可用于许多任务,包括找出文档中最常用的十几个单词、文件系统中最不常用的文件名、目录中最大的文件等等。但是,对于我们的任务,我们只想仔细检查日志文件,并找出将人们引导到我们网站的最频繁搜索

#!/bin/sh

ACCESSLOG="/var/logs/httpd.logs/access_log"

grep 'google.com/search' $ACCESSLOG | \
  awk '{print $11}' | \
  cut -d\? -f2 | cut -d\& -f1 | \
  sed 's/+/ /g;s/%22/"/g;s/q=//' | \
  sort | \
  uniq -c | \
  sort -rn | \
  head -5

结果是

$ sh google-searches.sh
 154 hl=en
  42 sourceid=navclient
  13 client=safari
   9 client=firefox-a
   3 sourceid=navclient-ff

嗯... 看起来这个脚本有问题,不是吗?

我将在这里结束,让您保持悬念到下个月。为什么不尝试找出可能存在的问题以及如何修复它,下个月我们将回到这个脚本,并弄清楚如何使其执行我们想要的操作,而不是我们说它应该执行的操作!

Dave Taylor 是 UNIX 领域的 26 年资深人士,The Elm Mail System 的创建者,最近还是畅销书 Wicked Cool Shell ScriptsTeach Yourself Unix in 24 Hours 的作者,以及他的 16 本技术书籍。他的主要网站是 www.intuitive.com

加载 Disqus 评论