注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

格物窮理 玄陰極地

生殺動靜 順勢擇吉

 
 
 

日志

 
 

(转载)Google投放广告的js的分析  

2012-03-01 10:43:53|  分类: hack |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
大家平时见到google的广告太多了,但有没有兴趣知道一下它的运行过程呢?

下面我们一起来看看这个广告代码的执行过程,以及其中的一些精彩内容。
阿权(hqlulu)平时也会投放google的广告,不过帐户还是$0.00,呵呵。
今天特意想研究一下它的运行过程,来给大家分享一下。

我们先看看下面的代码,是通过google的设置得到的:

  1. <script type="text/javascript"><!--
  2. google_ad_client = "pub-2063594891864588";
  3. google_ad_width = 728;
  4. google_ad_height = 90;
  5. google_ad_format = "728x90_as";
  6. google_ad_type = "text_image";
  7. google_ad_channel = "";
  8. google_color_border = "E6E6E6";
  9. google_color_bg = "E6E6E6";
  10. google_color_link = "000000";
  11. google_color_text = "333333";
  12. google_color_url = "666666";
  13. //--></script>
  14. <script type="text/javascript"
  15.   src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
  16. </script>
复制代码


明显,先设置一些参数,再调用该js文件,完成广告的投放。
下面把show_ads.js下载回来,我们分析一下:

首先就让我惊讶的是,文件里面首先就是一个这样的结构:
  1. (function(){……})()
复制代码


我特意发贴问了一下,谢谢mozart0给了他的看法,再次总结一下:
首先,从最后一个括号看出来,这个是调用一个对象,而这个对象就是 function(){……} 建立后返回的
mozart0说:“直观的好处是把几条需要顺序执行的语句组织成一个单元,使逻辑清晰,又不用为它取名字,可能出于节约的考虑:该匿名函数像一个临时变量,执行后可以被立即销毁,当然连同其中的局部变量”
总体而言,就是建立了一个对象,并且执行它,同时,销毁了一切,一定程度实现了对对象的保护和保密

(A)() 执行效果:先定义A对象,然后执行A对象,执行完毕,A对象就被销毁了

这个是一个不错的方法,值得大家学习借鉴。

好了,我们看看“……”里面的代码,看完一遍就知道它是做了什么。
我整理了一下,按层次结构排列好(这个过程花费的时间也不少呢),没有修改里面的代码,只是加了注释和层次关系的整理。

大体执行过程为:

01 定义字符串操作函数,往URL后添加各种参数 c(b,a) 等
02 定义收集用户端信息的函数 function D(b,a)
03 定义输出广告代码的函数function G(b,a,d)
04 定义对象重置的函数function F(b)
05 定义添加各种参数到URL的函数function A()
06 定义屏幕信息检测函数function x(b,a)
07 定义页面初始化函数function E()
08 运行初始化函数
09 处理应该带上的参数
10 收集客户端信息
11 按指定的方式输出广告代码
12 对象重置

可能因为技术上的问题,这段js代码里面的函数名称都是很奇怪的,为了增加用户查看的难度吧?
在这里仅列举几个函数,其余见后面附上的完整代码

1 往URL上添加参数

  1. //如果值存在,则在广告链接后面加上参数
  2. function c(b,a){
  3.         if(a){
  4.                 window.google_ad_url+="&"+b+"="+a
  5.         }
  6. }
复制代码


2 取得客户端信息

  1. //取得浏览器的参数 [执行步骤:03]
  2. //这个是属于用户调查啦,也没收集多少隐私吧,呵呵
  3. function D(b,a){
  4.         var d=b.screen,g=navigator.javaEnabled(),e=-a.getTimezoneOffset();
  5.         //用户浏览器属性
  6.         if(d){
  7.                 c("u_h",d.height);
  8.                 c("u_w",d.width);
  9.                 c("u_ah",d.availHeight);
  10.                 c("u_aw",d.availWidth);
  11.                 c("u_cd",d.colorDepth)
  12.         }
  13.         //用户时区
  14.         c("u_tz",e);
  15.         //用户历史记录长度
  16.         c("u_his",history.length);
  17.         //用户浏览器对java的设置
  18.         c("u_java",g);
  19.         //用户plugins长度
  20.         if(navigator.plugins){
  21.                 c("u_nplug",navigator.plugins.length)
  22.         }
  23.         //用户mimeTypes长度
  24.         if(navigator.mimeTypes){
  25.                 c("u_nmime",navigator.mimeTypes.length)
  26.         }
  27. }
复制代码


3 输出广告代码

  1. //输出广告代码到页面中 [执行步骤:04]
  2. function G(b,a,d){
  3.         d=d.substring(0,1000);
  4.         //用正则表达式去掉末尾的 %+单个字符
  5.         d=d.replace(/%\w?$/,"");
  6.         //按不同的广告类型,输出广告代码
  7.         //m函数是给数值两边加上引号
  8.         if(b.google_ad_output=="js"&&(b.google_ad_request_done||b.google_radlink_request_done)){
  9.                 //把广告代码的地址输出,加载该文件
  10.                 a.write('<script language="JavaScript1.1" src='+m(d)+"><\/script>")
  11.         }else if(b.google_ad_output=="html"){
  12.                 if(b.name!="google_ads_frame"){
  13.                                 a.write('<iframe name="google_ads_frame" width='+m(b.google_ad_width)+" height="+m(b.google_ad_height)+" frameborder="+m(b.google_ad_frameborder)+" src="+m(d)+' marginwidth="0" marginheight="0" vspace="0" hspace="0" allowtransparency="true" scrolling="no">');
  14.                                 a.write("</iframe>")
  15.                 }
  16.         }else if(b.google_ad_output=="textlink"){
  17.                 a.write('<script language="JavaScript1.1" src='+m(d)+"><\/script>")
  18.         }
  19. }

整个js文件整理之后的代码为:

  1. (function(){
  2.         // parse by hqlulu
  3.         // www.aslibra.com
  4.         // 2007-3-10

  5.         //返回把参数用引号括起来的值
  6.         function m(b){
  7.                 return b!=null?'"'+b+'"':'""'
  8.         }

  9.         //把参数转换字符
  10.         function B(b){
  11.                 if(typeof encodeURIComponent=="function"){
  12.                         return encodeURIComponent(b)
  13.                 }else{
  14.                         return escape(b)
  15.                 }
  16.         }

  17.         //如果值存在,则在广告链接后面加上参数
  18.         function c(b,a){
  19.                 if(a){
  20.                         window.google_ad_url+="&"+b+"="+a
  21.                 }
  22.         }

  23.         //把值转换字符并加到链接后面
  24.         function f(b,a){
  25.                 if(a){
  26.                         c(b,B(a))
  27.                 }
  28.         }

  29.         //如果中间的参数是对象的话,则取时间与对象长度余数的值?
  30.         function l(b,a,d){
  31.                 if(a&&typeof a=="object"){
  32.                         a=a[d%a.length]
  33.                 }
  34.                 c("color_"+b,a)
  35.         }

  36.         ///////////////  以上是定义在网址后加上参数的函数  ///////////////////

  37.         //取得浏览器的参数 [执行步骤:03]
  38.         //这个是属于用户调查啦,也没收集多少隐私吧,呵呵
  39.         function D(b,a){
  40.                 var d=b.screen,g=navigator.javaEnabled(),e=-a.getTimezoneOffset();
  41.                 //用户浏览器属性
  42.                 if(d){
  43.                         c("u_h",d.height);
  44.                         c("u_w",d.width);
  45.                         c("u_ah",d.availHeight);
  46.                         c("u_aw",d.availWidth);
  47.                         c("u_cd",d.colorDepth)
  48.                 }
  49.                 //用户时区
  50.                 c("u_tz",e);
  51.                 //用户历史记录长度
  52.                 c("u_his",history.length);
  53.                 //用户浏览器对java的设置
  54.                 c("u_java",g);
  55.                 //用户plugins长度
  56.                 if(navigator.plugins){
  57.                         c("u_nplug",navigator.plugins.length)
  58.                 }
  59.                 //用户mimeTypes长度
  60.                 if(navigator.mimeTypes){
  61.                         c("u_nmime",navigator.mimeTypes.length)
  62.                 }
  63.         }

  64.         //检查参数是否以 ca- 开始,否则添加 ca-
  65.         function y(b){
  66.                 b=b.toLowerCase();
  67.                 if(b.substring(0,3)!="ca-"){
  68.                         b="ca-"+b
  69.                 }
  70.                 return b
  71.         }

  72.         //输出广告代码到页面中 [执行步骤:04]
  73.         function G(b,a,d){
  74.                 d=d.substring(0,1000);
  75.                 //用正则表达式去掉末尾的 %+单个字符
  76.                 d=d.replace(/%\w?$/,"");
  77.                 //按不同的广告类型,输出广告代码
  78.                 //m函数是给数值两边加上引号
  79.                 if(b.google_ad_output=="js"&&(b.google_ad_request_done||b.google_radlink_request_done)){
  80.                         //把广告代码的地址输出,加载该文件
  81.                         a.write('<script language="JavaScript1.1" src='+m(d)+"><\/script>")
  82.                 }else if(b.google_ad_output=="html"){
  83.                         if(b.name!="google_ads_frame"){
  84.                                         a.write('<iframe name="google_ads_frame" width='+m(b.google_ad_width)+" height="+m(b.google_ad_height)+" frameborder="+m(b.google_ad_frameborder)+" src="+m(d)+' marginwidth="0" marginheight="0" vspace="0" hspace="0" allowtransparency="true" scrolling="no">');
  85.                                         a.write("</iframe>")
  86.                         }
  87.                 }else if(b.google_ad_output=="textlink"){
  88.                         a.write('<script language="JavaScript1.1" src='+m(d)+"><\/script>")
  89.                 }
  90.         }

  91.         //把对象的各个参数都置为null  [执行步骤:05] 结束
  92.         //因为页面里面有多个广告代码的话,就混乱了,所以执行这个,以便下一个广告
  93.         //同时,也防止页面里面直接用js查看设置的对象的值
  94.         function F(b){
  95.                 var a=null;
  96.                 b.google_ad_frameborder=a;
  97.                 b.google_ad_format=a;
  98.                 b.google_page_url=a;
  99.                 b.google_language=a;
  100.                 b.google_gl=a;
  101.                 b.google_country=a;
  102.                 b.google_region=a;
  103.                 b.google_city=a;
  104.                 b.google_hints=a;
  105.                 b.google_safe=a;
  106.                 b.google_encoding=a;
  107.                 b.google_ad_output=a;
  108.                 b.google_max_num_ads=a;
  109.                 b.google_ad_channel=a;
  110.                 b.google_contents=a;
  111.                 b.google_alternate_ad_url=a;
  112.                 b.google_alternate_color=a;
  113.                 b.google_color_bg=a;
  114.                 b.google_color_text=a;
  115.                 b.google_color_link=a;
  116.                 b.google_color_url=a;
  117.                 b.google_color_border=a;
  118.                 b.google_color_line=a;
  119.                 b.google_adtest=a;
  120.                 b.google_kw_type=a;
  121.                 b.google_kw=a;
  122.                 b.google_num_radlinks=a;
  123.                 b.google_max_radlink_len=a;
  124.                 b.google_rl_filtering=a;
  125.                 b.google_rl_mode=a;
  126.                 b.google_rt=a;
  127.                 b.google_ad_type=a;
  128.                 b.google_image_size=a;
  129.                 b.google_feedback=a;
  130.                 b.google_skip=a;
  131.                 b.google_page_location=a;
  132.                 b.google_referrer_url=a;
  133.                 b.google_ad_region=a;
  134.                 b.google_ad_section=a;
  135.                 b.google_bid=a;
  136.                 b.google_cpa_choice=a;
  137.                 b.google_cust_age=a;
  138.                 b.google_cust_gender=a;
  139.                 b.google_cust_interests=a;
  140.                 b.google_cust_id=a;
  141.                 b.google_cust_job=a;
  142.                 b.google_cust_u_url=a;
  143.                 b.google_cust_ch=a;
  144.                 b.google_ed=a;
  145.                 b.google_targeting=a;
  146.                 b.google_ad_host=a
  147.         }

  148.         //处理应该带上的参数以便显示广告 [执行步骤:02]
  149.         function A(){
  150.                 //这里有几种加上参数的形式
  151.                 //c 直接加上
  152.                 //f 转义后加上
  153.                 //l 加上对象中的参数?
  154.                 var b=null,a=window,d=document,g=new Date,e=g.getTime(),j=a.google_ad_format;
  155.                 if(a.google_cpa_choice){
  156.                         a.google_ad_url="http://pagead2.googlesyndication.com/cpa/ads?";
  157.                         a.google_ad_url+="client="+escape(y(a.google_ad_client));
  158.                         a.google_ad_region="_google_cpa_region_";
  159.                         c("cpa_choice",a.google_cpa_choice);
  160.                         if(typeof d.characterSet!="undefined"){
  161.                                 f("oe",d.characterSet)
  162.                         }else if(typeof d.charset!="undefined"){
  163.                                 f("oe",d.charset)
  164.                         }
  165.                 }else{
  166.                         a.google_ad_url="http://pagead2.googlesyndication.com/pagead/ads?";
  167.                         a.google_ad_url+="client="+escape(y(a.google_ad_client))
  168.                 }
  169.                 c("host",a.google_ad_host);
  170.                 var k=a.google_num_slots_by_client,w=a.google_num_slots_by_channel,i=a.google_prev_ad_formats_by_region;a.onerror=a.google_org_error_handler;
  171.                 if(a.google_ad_region==b&&a.google_ad_section!=b){
  172.                         a.google_ad_region=a.google_ad_section
  173.                 }
  174.                 var h=a.google_ad_region==b?"":a.google_ad_region,q=false;
  175.                 if(j){
  176.                         q=j.indexOf("_0ads")>0
  177.                 }
  178.                 if(q){
  179.                         if(a.google_num_0ad_slots){
  180.                                 a.google_num_0ad_slots=a.google_num_0ad_slots+1
  181.                         }else{
  182.                                 a.google_num_0ad_slots=1
  183.                         }
  184.                         if(a.google_num_0ad_slots>3){
  185.                                 return
  186.                         }
  187.                 }else if(!a.google_cpa_choice){
  188.                         if(a.google_num_ad_slots){
  189.                                 a.google_num_ad_slots=a.google_num_ad_slots+1
  190.                         }else{
  191.                                 a.google_num_ad_slots=1
  192.                         }
  193.                         if(a.google_num_slots_to_rotate){
  194.                                 i[h]=b;
  195.                                 if(a.google_num_slot_to_show==b){
  196.                                         a.google_num_slot_to_show=e%a.google_num_slots_to_rotate+1
  197.                                 }if(a.google_num_slot_to_show!=a.google_num_ad_slots){
  198.                                         return
  199.                                 }
  200.                         }else if(a.google_num_ad_slots>3&&h==""){
  201.                                 return
  202.                         }
  203.                 }
  204.                 c("dt",g.getTime());
  205.                 c("hl",a.google_language);
  206.                 if(a.google_country){
  207.                         c("gl",a.google_country)
  208.                 }else{
  209.                         c("gl",a.google_gl)
  210.                 }
  211.                 c("gr",a.google_region);
  212.                 f("gcs",a.google_city);
  213.                 f("hints",a.google_hints);
  214.                 c("adsafe",a.google_safe);
  215.                 c("oe",a.google_encoding);
  216.                 c("lmt",a.google_last_modified_time);
  217.                 f("alternate_ad_url",a.google_alternate_ad_url);
  218.                 c("alt_color",a.google_alternate_color);
  219.                 c("skip",a.google_skip);
  220.                 c("targeting",a.google_targeting);
  221.                 var n=a.google_ad_client;
  222.                 if(!k[n]){
  223.                         k[n]=1;k.length+=1
  224.                 }else{
  225.                         k[n]+=1
  226.                 }
  227.                 if(i[h]){
  228.                         f("prev_fmts",i[h].toLowerCase());
  229.                         if(k.length>1){
  230.                                 c("slot",k[n])
  231.                         }
  232.                 }
  233.                 if(j){
  234.                         f("format",j.toLowerCase());
  235.                         if(i[h]){
  236.                                 i[h]=i[h]+","+j
  237.                         }else{
  238.                                 i[h]=j
  239.                         }
  240.                 }
  241.                 c("num_ads",a.google_max_num_ads);
  242.                 c("output",a.google_ad_output);
  243.                 c("adtest",a.google_adtest);
  244.                 if(a.google_ad_channel){
  245.                         var r=a.google_ad_channel;
  246.                         f("channel",r);
  247.                         var s="",t=r.split("+");
  248.                         for(var o=0;o<t.length;o++){
  249.                                 var p=t[o];
  250.                                 if(!w[p]){
  251.                                         w[p]=1
  252.                                 }else{
  253.                                         s+=p+"+"
  254.                                 }
  255.                         }
  256.                         f("pv_ch",s)
  257.                 }
  258.                 //l 参数名称,对象,时间
  259.                 //开始处理js文件前面的颜色和大小等信息
  260.                 f("url",a.google_page_url);
  261.                 l("bg",a.google_color_bg,e);
  262.                 l("text",a.google_color_text,e);
  263.                 l("link",a.google_color_link,e);
  264.                 l("url",a.google_color_url,e);
  265.                 l("border",a.google_color_border,e);
  266.                 l("line",a.google_color_line,e);
  267.                 c("kw_type",a.google_kw_type);
  268.                 f("kw",a.google_kw);
  269.                 f("contents",a.google_contents);
  270.                 c("num_radlinks",a.google_num_radlinks);
  271.                 c("max_radlink_len",a.google_max_radlink_len);
  272.                 c("rl_filtering",a.google_rl_filtering);
  273.                 c("rl_mode",a.google_rl_mode);
  274.                 c("rt",a.google_rt);
  275.                 c("ad_type",a.google_ad_type);
  276.                 c("image_size",a.google_image_size);
  277.                 c("region",a.google_ad_region);
  278.                 c("feedback_link",a.google_feedback);
  279.                 f("ref",a.google_referrer_url);
  280.                 f("loc",a.google_page_location);
  281.                 c("bid",a.google_bid);
  282.                 c("cust_age",a.google_cust_age);
  283.                 c("cust_gender",a.google_cust_gender);
  284.                 c("cust_interests",a.google_cust_interests);
  285.                 c("cust_id",a.google_cust_id);
  286.                 c("cust_job",a.google_cust_job);
  287.                 c("cust_u_url",a.google_cust_u_url);
  288.                 c("cust_ch",a.google_cust_ch);
  289.                 c("ed",a.google_ed);
  290.                 if(z(a,d)&&d.body){
  291.                         var u=d.body.scrollHeight,v=d.body.clientHeight;
  292.                         if(v&&u){
  293.                                 f("cc",Math.round(v*100/u))
  294.                         }
  295.                 }

  296.                 //调用显示广告的代码
  297.                 D(a,g);
  298.                 G(a,d,a.google_ad_url);
  299.                 F(a)
  300.         }

  301.         //错误处理 window.onerror 则调用这个
  302.         function C(b,a,d){
  303.                 A();
  304.                 return true
  305.         }

  306.         //判断本页面是否处于框架内,不是则返回真
  307.         //(疑问:如果网页A包含网页A呢,导致死循环包含,加上脚本可以避免死循环呢?会不会出错?)
  308.         function z(b,a){
  309.                 return b.top.location==a.location
  310.         }

  311.         //b: window对象  a: document对象
  312.         //检测屏幕信息
  313.         function x(b,a){
  314.                 var d=a.documentElement;
  315.                 if(z(b,a))
  316.                         return false;
  317.                 //不处于框架中
  318.                 if(b.google_ad_width&&b.google_ad_height){
  319.                         var g=1,e=1;
  320.                         //检测可显示区域
  321.                         //参数意义可以参考:
  322.                         // JS测试屏幕信息 http://www.aslibra.com/down/test_info.html
  323.                         if(b.innerHeight){
  324.                                 g=b.innerWidth;e=b.innerHeight
  325.                         }else if(d&&d.clientHeight){
  326.                                 g=d.clientWidth;e=d.clientHeight
  327.                         }else if(a.body){
  328.                                 g=a.body.clientWidth;
  329.                                 e=a.body.clientHeight
  330.                         }
  331.                         if(e>2*b.google_ad_height||g>2*b.google_ad_width){
  332.                                 return false
  333.                         }
  334.                 }
  335.                 return true
  336.         }

  337.         //页面初始化处理 [执行步骤:01]
  338.         //建立对象,记录文件属性以及来源等信息
  339.         function E(){
  340.                 //定义错误处理
  341.                 var b=window,a=document,d=a.location,g=a.referrer,e=null;b.google_org_error_handler=b.onerror;b.onerror=C;
  342.                 //初始化window对象下的变量
  343.                 if(b.google_ad_frameborder==e){
  344.                         b.google_ad_frameborder=0
  345.                 }
  346.                 if(b.google_ad_output==e){
  347.                         b.google_ad_output="html"
  348.                 }
  349.                 if(b.google_ad_format==e&&b.google_ad_output=="html"){
  350.                         b.google_ad_format=b.google_ad_width+"x"+b.google_ad_height
  351.                 }
  352.                 if(b.google_page_url==e){
  353.                         b.google_page_url=g;
  354.                         if(!x(b,a)){
  355.                                 b.google_page_url=d;
  356.                                 b.google_last_modified_time=Date.parse(a.lastModified)/1000;
  357.                                 b.google_referrer_url=g
  358.                         }
  359.                 }else{
  360.                         b.google_page_location=g;
  361.                         if(!x(b,a)){
  362.                                 b.google_page_location=d
  363.                         }
  364.                 }
  365.                 if(b.google_num_slots_by_channel==e){
  366.                         b.google_num_slots_by_channel=[]
  367.                 }
  368.                 if(b.google_num_slots_by_client==e){
  369.                         b.google_num_slots_by_client=[]
  370.                 }
  371.                 if(b.google_prev_ad_formats_by_region==e){
  372.                         b.google_prev_ad_formats_by_region=[]
  373.                 }
  374.         }

  375.         //先检查处理页面参数
  376.         E();
  377.         //处理应该带上的参数
  378.         A();
  379. })()
  评论这张
 
阅读(556)| 评论(2)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017