zoukankan      html  css  js  c++  java
  • 抛砖系列之文本处理工具-awk

    AWK是一个优良的文本处理工具,Linux及Unix环境中现有的功能最强大的数据处理引擎之一。这种编程及数据操作语言(其名称得自于它的创始人阿尔佛雷德·艾侯、彼得·温伯格和布莱恩·柯林汉姓氏的首个字母)的最大功能取决于一个人所拥有的知识。awk经过改进生成的新的版本nawk,gawk,现在默认linux系统下日常使用的是gawk,用命令可以查看正在应用的awk的来源(ls -l /bin/awk )

    ​以上内容来源于百度百科

    场景1:

    某日,有个客户联系我们说:“门户上发布的中标信息好像被友商窃取了,刚发布一阵就出现在友商网站了”,我们立马去“友商”网站一探究竟,果不其然,一根烟的功夫就跑到友商那里了,这种事客户还是有点介意的,希望我们暂时从技术层面解决一下,如果对方依然“面向监狱编程”,他们就要走法律程序了。

    说到这儿我们暂时想了两个方案:

    1.假设对方爬虫是遵从robots协议的,那我们就“亮明身份“,通过robots协议告诉它们规矩点,对robots协议感兴趣的可以自己上网络了解,类似于这样:

    # 任何端不能爬取我站点的任何内容
    User-agent: *
    Disallow: /
    

      

    2.通过ip黑名单的方式拒绝爬虫ip访问

    这个应该是比较常规的手段了,难点的是如何找到这些ip呢?

    • 在请求日志中过滤UserAgent中带有spider关键字的?事实证明爬虫的伪装能力很强,不会用这么明显的UserAgent

    • 找访问频次比较高的ip呢?统计了一下都很平均

    最后通过对比请求参数的方式我找到了过滤规则,正常的请求分页参数pagestr都在合理的范围内,一共600页数据,普通用户翻页不会超过600的,前端已经避免了这种情况,而爬虫发出的请求,pagestr早已超过了600,所以过滤也就比较简单了,找出那些pagestr>600的请求ip就是爬虫了。

    看看我们系统配置的access log format

    %{client}a - %{dd/MMM/yyyy:HH:mm:ss Z|Asia/Shanghai|zh}t "%r" %s %O %D %{username}C %{traceId}i "%{User-Agent}i"
    59.52.50.24 - [23/八月/2021:10:05:34 +0800] "GET /portal/list?chnlcode=bidresult&objtype=&pagestr=200001&pageSize=10 HTTP/1.1" 200 28152 10000 - 2929b398758148738f584c7cf266fa0e "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36"
    

      

    1.grep一级过滤,找出要进行参数截取的请求日志

    grep '/portal/list?chnlcode=bidresult' 2021_08_23.request.log
    59.52.50.24 - [23/八月/2021:10:05:34 +0800] "GET /portal/list?chnlcode=bidresult&objtype=&pagestr=2&pageSize=10 HTTP/1.1" 200 28152 10000 - 2929b398758148738f584c7cf266fa0e "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36"
    59.52.50.24 - [23/八月/2021:10:06:01 +0800] "GET /portal/list?chnlcode=bidresult&objtype=&pagestr=3&pageSize=10 HTTP/1.1" 200 27996 9000 - 13f322d845de4cdc95bd464505a7a202 "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36"
    

    2.一步一步把pagestr截取出来

    grep '/portal/list?chnlcode=bidresult' 2021_08_23.request.log  | awk -F"HTTP/1.1" '{print $1}'  
    59.52.50.24 - [23/八月/2021:10:05:34 +0800] "GET /portal/list?chnlcode=bidresult&objtype=&pagestr=2&pageSize=10 
    59.52.50.24 - [23/八月/2021:10:06:01 +0800] "GET /portal/list?chnlcode=bidresult&objtype=&pagestr=3&pageSize=10
    grep '/portal/list?chnlcode=bidresult' 2021_08_23.request.log  | awk -F"HTTP/1.1" '{print $1}' | awk -F"pagestr=" '{ print $1,$2}'
    59.52.50.24 - [23/八月/2021:10:05:34 +0800] "GET /portal/list?chnlcode=bidresult&objtype=& 20001&pageSize=10 
    59.52.50.24 - [23/八月/2021:10:06:01 +0800] "GET /portal/list?chnlcode=bidresult&objtype=& 30001&pageSize=10
    

    awk -F 通过指定分隔符拆分字符串,相当于java中split。

    截止现在我们拿到了”pagestr=“作为分隔符的左右两侧的值,分别是:

    左侧

    59.52.50.24 - [23/八月/2021:10:05:34 +0800] "GET /portal/list?chnlcode=bidresult&objtype=&

    右侧

    2&pageSize=10

    左侧有我们需要的ip(59.52.50.24),右侧有我们需要的pagestr(2),只是pagestr现在和其他参数黏在一起(2&pageSize=10),似乎不能直接拿来用。

    3.通过pagestr过滤请求信息

    grep '/portal/list?chnlcode=bidresult' 2021_08_23.request.log  | awk -F"HTTP/1.1" '{print $1}' | awk -F"pagestr=" '{if($2>600) print $1}
    59.52.50.24 - [23/八月/2021:10:05:34 +0800] "GET /portal/list?chnlcode=bidresult&objtype=&
    59.52.50.24 - [23/八月/2021:10:06:01 +0800] "GET /portal/list?chnlcode=bidresult&objtype=&
    

    这里通过if($2>600)作为判断条件输出$1中的内容,也就是请求信息,也许你会问了,$2不是“2&pageSize=10”这种形式的混合字符串吗,怎么能和数字直接比大小呢?这个就是awk的神奇之处了,这里有个隐式的转换,“自动强制将字符串转为整型。非数字变成0,发现第一个非数字字符,后面自动忽略”。

    4.输出请求信息中的ip地址

    grep '/portal/list?chnlcode=bidresult' 2021_08_23.request.log  | awk -F"HTTP/1.1" '{print $1}' | awk -F"pagestr=" '{if($2>600) print $1} | sort | uniq -c
    ​
    

      

    场景2:

    “统计下响应时间超过1s的url”,这个场景算是很常见的了,话不多少,直接上命令,场景1中已经交代了我们系统配置的access log format,其中有一列代表了响应时间,那我们直接用它作为过滤条件即可。

    awk '{if($10>1000000) print $1,$2,$8,$9}' 2021_08_23.request.log

    这里没有指定-F时默认以“空格”作为分隔符,这个场景下“空格”分隔完就完全够用了。

    推荐阅读

    https://linuxhandbook.com/awk-command-tutorial/

    通过两个场景作为awk的“抛砖”,更多更精彩的玩法网络上已经有很多的案例,我就不啰嗦了。

     

      

  • 相关阅读:
    关于回调地狱
    node.js 关于跨域和传递给前台参数
    关于js的当前日期的格式化,和两个日期之间的相减的天数
    CSS 关于让页面的高度达到电脑屏幕的底部
    前端 为什么我选择用框架而不是Jquery
    关于webpack打包图片的路径问题
    关于webpack打包js和css
    微信小程序网络请求的setDate
    WinSocket聊天程序实例(多线程)
    Orcal的JDBC数据连接方式
  • 原文地址:https://www.cnblogs.com/chopper-poet/p/15184516.html
Copyright © 2011-2022 走看看