⑴ 0谁能告诉我google邮箱申请页的URL
http://mail.google.com/mail/a-38555ea909-0171b6ae9e-29159572d6
你怎么还不申请阿?
⑵ 关于谷歌分析的自定义过滤器
过滤器个我生气了
⑶ 联网了但是手机进不了浏览器,网页显示“检查Google提供的该网页的缓存副本”是什么意思
缓存副本就是google网页快照。
⑷ 基于布隆过滤器的非法URL识别,有没有能用Java
假如有1亿个不重复的正整数(大致范围已知),但是只有1G的内存可用,如何判断该范围内的某个数是否出现在这1亿个数中?最常用的处理办法是利用位图,1*108/1024*1024*8=11.9,也只需要申请12M的内存。但是如果是1亿个邮件地址,如何确定某个邮件地址是否在这1亿个地址中?这个时候可能大家想到的最常用的办法就是利用Hash表了,但是大家可以细想一下,如果利用Hash表来处理,必须开辟空间去存储这1亿个邮件地址,因为在Hash表中不可能避免的会发生碰撞,假设一个邮件地址只占8个字节,为了保证Hash表的碰撞率,所以需要控制Hash表的装填因子在0.5左右,那么至少需要2*8*108/1024*1024*1024=1.5G的内存空间,这种情况下利用Hash表是无法处理的。这个时候要用到另外一种数据结构-布隆过滤器(Bloom Filter),它是由Burton Howard Bloom在1970年提出的,它结合了位图和Hash表两者的优点,位图的优点是节省空间,但是只能处理整型值一类的问题,无法处理字符串一类的问题,而Hash表却恰巧解决了位图无法解决的问题,然而Hash太浪费空间。针对这个问题,布隆提出了一种基于二进制向量和一系列随机函数的数据结构-布隆过滤器。它的空间利用率和时间效率是很多算法无法企及的,但是它也有一些缺点,就是会有一定的误判率并且不支持删除操作。
布隆过滤器的原理
1
布隆过滤器需要的是一个位数组(这个和位图有点类似)和k个映射函数(和Hash表类似),在初始状态时,对于长度为m的位数组array,它的所有位都被置为0
2
对于有n个元素的集合S={s1,s2......sn},通过k个映射函数{f1,f2,......fk},将集合S中的每个元素sj(1<=j<=n)映射为k个值{g1,g2......gk},然后再将位数组array中相对应的array[g1],array[g2]......array[gk]置为1:
3
如果要查找某个元素item是否在S中,则通过映射函数{f1,f2.....fk}得到k个值{g1,g2.....gk},然后再判断array[g1],array[g2]......array[gk]是否都为1,若全为1,则item在S中,否则item不在S中。这个就是布隆过滤器的实现原理。
当然有读者可能会问:即使array[g1],array[g2]......array[gk]都为1,能代表item一定在集合S中吗?不一定,因为有这个可能:就是集合中的若干个元素通过映射之后得到的数值恰巧包括g1,g2,.....gk,那么这种情况下可能会造成误判,但是这个概率很小,一般在万分之一以下。
很显然,布隆过滤器的误判率和这k个映射函数的设计有关,到目前为止,有很多人设计出了很多高效实用的hash函数。并且可以证明布隆过滤器的误判率和位数组的大小以及映射函数的个数有关。假设误判率为p,位数组大小为m,集合数据个数为n,映射函数个数为k,它们之间的关系如下:
p=2-(m/n)*ln2 可得 m=(-n*lnp)/(ln2)2=-2*n*lnp=2*n*ln(1/p)
k=(m/n)*ln2=0.7*(m/n)
可以验证若p=0.1,(m/n)=9.6,即存储每个元素需要9.6bit位,此时k=0.7*(m/n)=6.72,即存储每个元素需要9.6个bit位,其中有6.72个bit位被置为1了,因此需要7个映射函数。从这里可以看出布隆过滤器的优越性了,比如上面例子中的,存储一个邮件地址,只需要10个bit位,而用hash表存储需要8*8=64个bit位。
一般情况下,p和n由用户设定,然后根据p和n的值设计位数组的大小和所需的映射函数的个数,再根据实际情况来设计映射函数。
尤其要注意的是,布隆过滤器是不允许删除元素的,因为若删除一个元素,可能会发生漏判的情况。不过有一种布隆过滤器的变体Counter Bloom Filter,可以支持删除元素,感兴趣的读者可以查阅相关文献资料。
END
布隆过滤器的应用
布隆过滤器在很多场合能发挥很好的效果,比如:网页URL的去重,垃圾邮件的判别,集合重复元素的判别,查询加速(比如基于key-value的存储系统)等,下面举几个例子:
1.有两个URL集合A,B,每个集合中大约有1亿个URL,每个URL占64字节,有1G的内存,如何找出两个集合中重复的URL。
很显然,直接利用Hash表会超出内存限制的范围。这里给出两种思路:
第一种:如果不允许一定的错误率的话,只有用分治的思想去解决,将A,B两个集合中的URL分别存到若干个文件中{f1,f2...fk}和{g1,g2....gk}中,然后取f1和g1的内容读入内存,将f1的内容存储到hash_map当中,然后再取g1中的url,若有相同的url,则写入到文件中,然后直到g1的内容读取完毕,再取g2...gk。然后再取f2的内容读入内存。。。依次类推,知道找出所有的重复url。
第二种:如果允许一定错误率的话,则可以用布隆过滤器的思想。
2.在进行网页爬虫时,其中有一个很重要的过程是重复URL的判别,如果将所有的url存入到数据库中,当数据库中URL的数量很多时,在判重时会造成效率低下,此时常见的一种做法就是利用布隆过滤器,还有一种方法是利用berkeley db来存储url,Berkeley db是一种基于key-value存储的非关系数据库引擎,能够大大提高url判重的效率。
布隆过滤器的简易版本实现:
#include<iostream>
#include<bitset>
#include<string>
#define MAX 2<<24
using namespace std;
bitset<MAX> bloomSet; //简化了由n和p生成m的过程
int seeds[7]={3, 7, 11, 13, 31, 37, 61}; //使用7个hash函数
int getHashValue(string str,int n) //计算Hash值
{
int result=0;
int i;
for(i=0;i<str.size();i++)
{
result=seeds[n]*result+(int)str[i];
if(result > 2<<24)
result%=2<<24;
}
return result;
}
bool isInBloomSet(string str) //判断是否在布隆过滤器中
{
int i;
for(i=0;i<7;i++)
{
int hash=getHashValue(str,i);
if(bloomSet[hash]==0)
return false;
}
return true;
}
void addToBloomSet(string str) //添加元素到布隆过滤器
{
int i;
for(i=0;i<7;i++)
{
int hash=getHashValue(str,i);
bloomSet.set(hash,1);
}
}
void initBloomSet() //初始化布隆过滤器
{
addToBloomSet("http://www..com");
addToBloomSet("http://www.cnblogs.com");
addToBloomSet("http://www.google.com");
}
int main(int argc, char *argv[])
{
int n;
initBloomSet();
while(scanf("%d",&n)==1)
{
string str;
while(n--)
{
cin>>str;
if(isInBloomSet(str))
cout<<"yes"<<endl;
else
cout<<"no"<<endl;
}
}
return 0;
}
⑸ URL怎么去优化
1)域名的选择
如果是在两年前,我会告诉大家域名中最好放上关键词。不过现在建议大家域名中能放关键词最好,但不要为了放关键词把域名弄的很长,更不要为了放关键词,注册带有连词符的域名。
再退一步,为让域名看得清楚,可以放一个连词符,最多放两个,但是不要为了堆积关键词。如果带有关键词的域名不好找,宁可选择一个容易品牌化的短的生僻词,或者新造的词。
2)描述性
整个URL包括域名,目录名和文件名,在可能的情况下,用具有描述性的单词,尤其是目录名和文件名。让用户看到URL,就可以大致了解这个网页是什么内容。
3)URL里面的关键词
在可能的情况下,目录名文件名可以放上一些关键词。Matt Cutts在他的一个帖子里面曾经暗示过,URL中的关键词多少对搜索引擎算法有用。
4)URL不可太长
虽然可以考虑在URL中放关键词,但最好不要为了放关键词,而把目录名文件名弄的很长。
5)用连词符
URL中目录名文件名单词之间最好用连词符-,不要用下划线_,也不要用其他允许但很奇怪的字符。连词符会被当作空格处理。
6)英文单词和拼音
对英文网站来说,当然URL中的描述性关键词比较好写。对中文网站可以考虑实使用拼音。但是对比较长的词,用拼音就不容易读懂,这种情况下还是建议使用英文单词。
另外有的人把目录名文件名里面放上中文字,或者有时候有空格,这样的URL出现在浏览器地址栏的时候,都会变成一些编码字符。虽然搜索引擎可以辨识,但看起来很难看,不建议。
7)URL静态化
这几乎是必须的。别较真,不要争辩说有很多带有一两个问号的URL都收录的很好。能做的更好也很简单,就不要去跟做的不好的看齐。
8)二级域名和目录
二级域名在中文网站里面似乎很流行,而且现在二级域名在Google里面有大量的垃圾内容,Google对此还没有什么好的办法。
不过我个人还是建议使用目录,除非有特别需要的时候,最好不要使用二级域名。
9)大小写
URL中最好统一全部使用小写字母,像Unix/Linux服务器大小写字母是不同处理的,也就是说Index.html和index.html是被当作两个不同的文件。如果一个目录下面的首页是Index.html,访问目录的时候就会出错。在其他情况下大小写混用也经常会造成混乱。
⑹ chrome 插件开发一个url拦截,重定向到另外一个地址,怎样做本地缓存
开始
为了着手创建你的扩展程序,你只需要为你的扩展创建一个文件夹。程序所必须的文件只有manifest.json.,不过也推荐准备一些图片用作图标,和至少一个JavaScript以提供功能。一般来说还会包含HTML文档、样式表、图片等等其他的资源。
Manifest文件
每个扩展都必须在其根目录下包含一个manifest.json文件。
这个文件里面声明了扩展的名称、版本、权限、设置选项和其他的一些和扩展相关的元数据。Manifest v1早在Chrome 18便已被弃用,而且会根据这个时间表逐渐淘汰使用Manifest v1的扩展。如果你在参考一些旧扩展的Manifest文件的话,请确认添加"manifest_version": 2.
Google发布的Manifest v2中支持的域
后台页
大多数扩展都会在其manfiest.json文件内有这样的内容:
1
2
3
4
5
{
"background": {
"scripts": ["index.js", "other.js"]
}
}
这一段代码指定了两个需要被加载而且要保持在后台运行的脚本,这些脚本会在扩展的后台页运行。后台页是一个在扩展的进程中生成并运行的页面,存在时间会和扩展的生命周期等长。后台页可用来作为扩展的其他界面的控制器,用来维护某个状态或者保持某些活动。如果你需要用后台页来声明一些标记来用,可以把一个HTML文件名指定给page选项。事件页
后台页会从扩展被加载的时候被装载,而且会一直留在内存里。这是因为如果有些状态需要被长时间维护,或者需要被扩展的其他部分访问。但是如果你没有这个需求,那么应该尽可能的使用事件页。事件页其实只是相当于一个包含了地persistent地: false条目的后台页,这一行语句告诉Chrome可以不需要把后台页保留在内存里。相对来说,事件页也会在最开始被装载,但是一旦指定的脚本运行完毕,事件页便会从内存卸载,而且会在需要的时候被再次加载(比如用来回应某些操作)。以上便是在为扩展添加功能之前所需要知道的。
交互
利用Google提供的大量API,你的扩展与浏览器交互或者为用户提供功能都变得方便。
chrome.* APIs
Chrome的程序和扩展程序都非常喜欢调用chrome.* APIs,这些API可以让你通过不同的方式来操控浏览器,API通常会在后台脚本里面被调用,这是我找到的一些常用API:
chrome.tabs 标签页:新建、刷新、关闭、访问和操控标签页
chrome.history 历史:访问用户浏览历史
chrome.bookmarks 书签:添加、编辑、移除和搜索用户书签
chrome.events 事件:监听或者管理浏览器发生的事件
chrome.commands 命令:添加或者改变键盘命令
chrome.contextMenus 右键:添加条目到右键下文菜单
chrome.omnibox 多功能框(地址栏):添加多功能框关键字,使用户可以向扩展发送指令或者激活扩展
其他API
Chrome程序和扩展程序通常也会用到其他的API,包括如本地存储、地理位置、缓存、画布等新型的HTML5 API。你也可以用普通的JavaScript或者webkit API来实现。声明权限
有些Chrome API的功能必须要在manifest.json文件中声明相关权限才能被调用,通过在permissions 域中把值设成相应权限名称,或者是通识符组成的数组。
1
2
3
4
5
6
7
8
{
"permissions": [
"contextMenus",
"tabs",
"*",
"*"
]
}
在这一段声明代码中,数组中的头两个字符串是分别用来为chrome.contextMenus和chrome.tabs 的API授权的,最后的两个字符串则是用来匹配以 和 开头的地址。用户界面
Chrome扩展的用户界面有着严格的限制,但是根据扩展的需要却可以有不同形式的界面。浏览器按钮[a]
浏览器按钮允许你在右上角放置一个的16 x 16像素的图标,如果扩展应用的界面是全局的,而不是针对某个页面,那就应该使用浏览器操作。如果要使用浏览器按钮,你必须在manifest.json中的browser_action域中做如下声明:
1
2
3
4
5
6
7
8
9
10
{
"browser_action": {
"default_icon": {
"19": "images/icon19.png",
"38": "images/icon38.png"
},
"default_title": "tooltip text here",
"default_popup": "popup.html"
}
}
一个浏览器按钮可以有一个图标、提示、文字标记和一个弹出内容,文字标记可以将极少的文字(4字符)动态的覆盖在浏览器操作的图标上,你也可以通过chrome.browserActionAPI来对浏览器按钮相关的事件做出反应。页面按钮
页面按钮允许你在多功能栏(地址栏)右边添加一个按钮,其实他和浏览器按钮很相似,区别之处在于页面按钮是专门用来处理某些指定的页面的。页面按钮必须在manfiest.json中声明, page_action域的使用和浏览器按钮一样。页面按钮可以通过chrome.pageAction API控制,可以在不同的标签页中灵活的显示或者隐藏。页面按钮也可以设置图标、提示和弹出内容,和浏览器按钮不同的是其没有文字标记功能。右键菜单
右键菜单是另一个提供用户界面,方便用户和扩展交互的方式。Chrome的右键菜单通过右键激活,但根据激活内容的变化,菜单内容也会做相应改变。
chrome.contextMenusAPI允许你向为不同内容激活的右键菜单添加项目,若要使用此API,则在manifest.json文件中声明相应的contextMenus权限。
目前可用的激活内容有:
all, page, frame, selection, link, editable,image, video, audio
对应:所有内容、页面、框架、选择、链接、可编辑、图像、视频、音频,以下这个例子需要contextMenus 和tabs权限,他可以使扩展为右键菜单添加一个根项目,然后添加一个子菜单,用来复制当前的页面到一个新选项卡。[b]
1
2
3
4
5
6
7
8
9
10
11
12
13
var root = chrome.contextMenus.create({
title: 'MyExtension',
contexts: ['page']
}, function () {
var subMenu = chrome.contextMenus.create({
title: 'Duplicate Tab'
contexts: ['page'],
parentId: root,
onclick: function (evt) {
chrome.tabs.create({ url: evt.pageUrl })
}
});
});
多功能框
Chrome把地址栏/搜索栏称为多功能框,通过chrome.omnibox API,他可以让扩展有另一个界面。通过API 可以设置一个特定的激活字符串,当这个字符串被键入多功能框时扩展便可以对其做出反应。在manifest.json中做如下声明:
1
2
3
4
5
{
"omnibox": {
"keyword": "ext-"
}
}
这部分代码会把ext-作为激活字符串,当用户键入ext-并按下SPACE键或者TAB键时扩展会被激活。激活字符串必须通过manifest.json文件声明,故也不能通过JavaScript来更改。用户可以通过右键单击多功能框—–修改搜索引擎来更改。激活字符串是大小写敏感的,同时想为一个扩展声明多个激活字符串也是不可以的。
chrome.omnibox API可以让你添加激活字符串被键入之后的修改或者输入的事件处理器。选项页面
选项页面是一个的常见的用户界面,在chrome://extensions里可以通过单击扩展右边的选项按钮来打开。通常这个页面会和存储API结合使用,以用来在计算机上为用户保存设置。而使用脚本通过chrome.tabsAPI来打开选项页面也是可以的。页面重载
页面重载允许你完全替代一个以下指定页面(一个扩展程序只能重载一个页面)
书签管理器
通过访问chrome://bookmarks或者Chrome菜单打开的页面
历史
通过访问chrome://history或者Chrome菜单打开的页面
新选项卡
通过访问chrome://newtab或者新建选项卡出现的页面
这些被替换的页面必须在manifest.json文件中如下声明chrome_url_overrides域:
1
2
3
4
5
{
"chrome_url_overrides": {
"bookmarks": "newBookmarkManager.html"
}
}
内容脚本
内容脚本是和你的扩展有关,在网页中运行的脚本。这个脚本可以让你访问页面里相应的DOM元素,你可以像这样在manifest.json里通过指定content_scripts域定义一个内容脚本数组:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
{
"content_scripts": [
{
"matches": ["*"],
"css": ["custom-google-styles.css"],
"js": ["custom-google-script-1.js", "custom-google-script-2.js"]
},
{
"matches": ["http://*"],
"css": ["global-styles.css"],
"js": ["global-script.js"]
}
]
}
你也可以用通过chrome.tabs API以动态的把JavaScript或者CSS注入网页。
内容脚本有以下限制:
不能使用chrome.* API (chrome.extension的部分除外)
不能使用由扩展脚本定义的变量或函数
不能使用由网页所定义的变量或函数
不能使用由其他内容脚本定义的变量或函数
内容脚本可以通过消息传递间接的使用chrome.* API,或者是和扩展脚本交互。