ModHeader顾名思义就是让咱们能够自定义HTTP请求头或者是重写响应头,包括新增请求头/响应头或者覆盖Chrome浏览器设置的请求头的默认值,同时还能够根据URL Pattern来只对特定网站生效。html
Request header用来定义请求头,Response header用来定义响应头,Filter用来设置针对特定网站生效:ajax
为何我须要这么一款看上去没啥用的插件呢?由于在实际的爬虫任务中碰到一个问题,要爬取的网站是个国外的网站,而如今稍具规模的网站都喜欢搞国际化,就是针对不一样国家的访客显示不一样的语言,理论上这样对用户更友好(实际上国际化若是作得不够好的话会有点奇怪...),这样就不用让用户再去找翻译软件翻译了,并且国际化是人设置的理论上要比翻译软件更好一些。api
那国际化是经过什么实现的呢?HTTP请求头有一项叫作Accept-Language,就是用来向服务器声明应该优先给本身显示什么语言。Chrome浏览器在发送请求的时候会根据浏览器当前的语言偏好设置这个请求头的值:浏览器
好比个人浏览器设置如上图,而后请求时Chrome就会将Accept-Language设置成这样的:缓存
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
目标网站虽然是外国网站,可是它接收到个人请求而后从请求头中拿出Accept-Language一看,呦,稀客呀,有zh-CN,说明访客要求优先查看简体中文,而后它就从配置好的一个国际化文件中取出中文的语言配置,这个配置文件简陋点的话就相似于这种:服务器
cn.welcome=欢迎访问咱们的网站 cn.vote=顶 cn.next_page=下一页 cn.previous_page=上一页
而后HTML页面上对应的位置都不直接写常量而是用一个变量来代替,变量就对应着上面这个配置文件中的键名去除cn.以后的部分,好比${vote},这样根据不一样状况加载不一样语言配置文件而后使用变量的值渲染页面就能够实现显示不一样语言,可是理想很丰满,现实很骨感,上面这个配置文件并不必定能覆盖到页面中的全部变量,也就是说如今页面上有一个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的话容易误判,好比挂了代理,好比肉身翻~墙(居然会被断定为敏感字没想到博客园也搞这一套...)想使用母语等状况,而Accept-Language通常都是浏览器设置的,浏览器更知道当前的系统环境应该是哪一种语言在安装时就能够自动设置为正确的语言,而后又提供了修改途径来让用户能够手动修正,这种方式更可靠。网站
不少网站都会有简单的反爬措施,比较常见的是加密参数,加密参数的其中一种形式是使用自定义的请求头来设置,好比下面这个请求头:加密
:authority: api.joom.com :method: GET :path: /1.1/products/1498834929187697429-213-1-709-71790600/sizeTables?currency=USD&language=en-US&_=joaauqxc :scheme: https accept: */* accept-encoding: gzip, deflate, br accept-language: zh-CN,zh;q=0.9,en;q=0.8 authorization: Bearer SEV0001MTU0MTc0ODc0N3xoSjZTMmF4TFp0MVZrQkgwcXc4X3cwVGRiX0dseFM0RjRVZS04Nk1Benl1X01YSHZKb3loSEFYT2IzQUVXOXdvRDJuSktScW4zbUpQd0tYTHlkendxQU9VdWZjSUVQVEJROGNGSW9qMFdUNHJpdllfUXlmd2NteVYxUVFaMUc3VS1mNk8yZXoxTnhuTWs4S1VVdTV2bU5xeExBZzlhMjZqTmpWdkRQc0FjbWVpMDFNPXz8wew7uOVGWgeKLikgiRVDi4EmSZ3N2dmd-5sz1ZKJDg== origin: https://www.joom.com referer: https://www.joom.com/en/products/1498834929187697429-213-1-709-71790600?context=%7B%22type%22%3A%22product%22%2C%22value%22%3A%5B%7B%22id%22%3A%221498834929187697429-213-1-709-71790600%22%2C%22type%22%3A%22pg%22%2C%22data%22%3A%22y8uHh4eH%2BflmZgEBAAAAAO1HA4bkpTdGfDfwd76maex7tY%2BDeOsoQUhHQ7m2bGbcRnL8SepQJnnjmW%2B10ic5dGbC4wTPTC6G%2FdUSDzg9vvCpZbGGn0A9FvtSYWiLaNQDYhLKWRek418JZf6%2FPEoE4uZrORmz2FOLRVs8jawo0mOraVj7rNDBuV5zDpWydGl4sCqPbnyg4zpOuTc%2FM418b4ysw%2BflK73seqQVTEKL4wf1J7sS8PX6EC%2Bpz3QhJdFzxIZc7jcjd%2BtWupz56QyQ53V4tyHQH0c%2Bu7tMzGXLkfnEC8je6m4tjnpJzuwV%2Frb%2FxFSyas0dJ73s%2BgFBPnLHnDdj9vDqklT3iEf2F8GCKBVK48lY8AWNcv%2B0kNzAprv6cXnXfH%2Fu0B0kbrEy4BRIr3Kh5lgbtkI6hU%2FXmwsRPYAWR9FVlTsLNQelBHe0yfRYz5rZhuRLd69n8q%2BKSdGPVXY58SWRmHxVtQDUxFCgqQQnMJX3DtnN1adOarhUzlEp%22%7D%5D%7D&contextSeed=1nk09 user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36 x-api-token: Uq4BiAM0c5yL22uuODvHe7GkBYSIDfVv x-ostype: Windows x-version: 0.1.15
其中的两个参数x-api-token和authorization看上去很可疑,怎么快速肯定哪一个请求头是必需要设置的呢?咱们可不想花费太多时间在非必要参数上,固然能够写点代码一点一点测试出来,好,如今来将难度再升级一下,假如这些参数都是动态生成的,每次都不同,即便将它们的值复制到程序中也不能用,也就是要在程序中模拟必需要先搞清楚这些值是如何来的,但是又不想花半天时间好不容易搞清楚一个请求头怎么来的忽然发现这个请求头不设置也能够,只好在内心默默流泪... (╥╯^╰╥)
首先屏蔽掉x-api-token这个请求头:
而后刷新网页,观察请求数据的那个ajax请求的请求头:
x-api-token这个请求头没有设置依然返回了数据,说明它应该不是必要参数,没必要再在这上面花费力气了。
再来试一下authorization:
清除缓存刷新:
不传这个参数页面直接挂掉了,连去请求商品详情的ajax请求都没有发送,说明这个参数应该是必须的,可以使用一样方法排查其它请求头。
总结:使用ModHeader快速肯定哪些请求头是必须的,提升分析目标网站的效率。
.