Chrome插件之ModHeader

一、ModHeader是什么

ModHeader顾名思义就是让我们可以自定义HTTP请求头,包括新增请求头或者覆盖Chrome浏览器设置的请求头的默认值,同时还可以根据URL Pattern来只对特定网站生效。

image

二、在爬虫开发中的一个应用场景(爬取网站时的语言设置问题)

为什么我需要这么一款看上去没啥用的插件呢?因为在实际的爬虫任务中碰到一个问题,要爬取的网站是个国外的网站,而现在稍具规模的网站都喜欢搞国际化,就是针对不同国家的访客显示不同的语言,理论上这样对用户更友好(实际上国际化如果做得不够好的话会有点奇怪...),这样就不用让用户再去找翻译软件翻译了,而且国际化是人设置的理论上要比翻译软件更好一些。

那国际化是通过什么实现的呢?HTTP请求头有一项叫做Accept-Language,就是用来向服务器声明应该优先给自己显示什么语言。Chrome浏览器在发送请求的时候会根据浏览器当前设置的语言设置这个请求头的值:

image

比如我的浏览器设置如上图,然后请求时Chrome就会将Accept-Language设置成这样的:

Accept-Language: zh-CN,zh;q=0.9,en;q=0.8

目标网站虽然是外国网站,但是它接收到我的请求然后从请求头中拿出Accept-Language一看,呦,稀客呀,有zh-CN,说明访客要求优先查看简体中文,然后它就从配置好的一个国际化文件中取出中文的语言配置,这个配置文件简陋点的话就类似于这种:

welcome=欢迎访问我们的网站
vote=顶
next_page=下一页
previous_page=上一页

然后HTML页面上对应的位置都不直接写常量而是用一个变量来代替,变量就对应着上面这个配置文件中的键名,这样根据不同情况加载不同语言配置文件然后使用变量的值渲染页面就可以实现显示不同语言,但是理想很丰满,现实很骨感,上面这个配置文件并不一定能覆盖到页面中的所有变量,也就是说现在页面上有一个foo变量在上面的配置文件中找不到对应的中文值怎么办,总不能空着吧,算了就先拿默认语言英文顶一下吧,于是就出现了有坑爹的国际化一半中文一半英文。这对人来说当然无所谓,但是对于程序来说区别就很大了,如果在程序中手动设置Accept-Language的话,比如我手动设置了优先中文,那么很多东西都会变成我所熟悉的,举个例子比如数字的显示方式,在我们国家使用逗号做千位分隔符,使用点做小数分隔符,比如一千零一点一,在我们国家一般会写成成“1,001.1”,而在某些欧洲国家,正好是反着来的,它们使用逗号做小数分隔符,使用点做千位分隔符,就会写做“1.001,1”,乍一看是让人懵逼的(维基百科 - 小数点),同理还有对日期的显示,如果能将这些使用中国的方式显示,看起来和解析起来都会爽很多,可是它们这种迷之国际化页面中哪些是中文哪些是英文是不受我控制的,很有可能他们稍稍一改我的程序就挂了,或者某个关键字段之前是用英文显示的某一天突然变中文了...写代码时应该尽量减少不可控因素所占的比重,所以没有特殊情况的话,我们在爬取一个网站时使用的语言应该尽量是这个网站的默认语言,即不设置Accept-Language这个请求头即可。

但是另一个问题又来了(我勒个天跑题半天终于绕回来了),我程序中没有设置Accept-Language,然后我热心肠的Chrome浏览器帮我设置了Accept-Language,然后我在Chrome中使用开发者工具排查问题时看到的页面的语言就跟我程序中的不一致,如果调整Chrome的语言设置的话虽然能解决问题但是这个设置是全局的会对所有网站都有影响,搞不好我以后访问一个有国际化的中文网站,它一看我的Accept-Language是以en打头的二话不说返回给了我英文版的网站,我找谁说理去...这个时候终于轮到在门外站了半天的ModHeader出场了,使用ModHeader将Chrome浏览器的Accept-Language调整为和程序中的一致即可,即手动设置为想要的语言或置空,然后在URL Pattern只匹配目标网站,这样至少在浏览器中看到的语言和程序中是一致的,而且对访问其它站点也没有影响,也算是爬取国外网站调试的一个小技巧吧。

最后解释一下为什么国际化使用Accept-Language而不是基于IP做判别,因为基于IP的话容易误判,比如挂了代理,比如肉身FQ想使用母语等情况,而Accept-Language一般都是浏览器设置的,浏览器更知道当前的系统环境应该是哪种语言在安装时就可以自动设置为正确的语言,然后又提供了修改途径来让用户可以手动修正,这种方式更可靠。

.

猜你喜欢

转载自www.cnblogs.com/cc11001100/p/9788683.html