Chrome插件之ModHeader
⼀、ModHeader是什么
ModHeader顾名思义就是让我们可以⾃定义HTTP请求头或者是重写响应头,包括新增请求头/响应头或者覆盖Chrome浏览器设置的请求头的默认值,同时还可以根据URL Pattern来只对特定⽹站⽣效。
Request header⽤来定义请求头,Response header⽤来定义响应头,Filter⽤来设置针对特定⽹站⽣效:
⼆、在爬⾍开发中的应⽤场景
2.1 爬取⽹站时的语⾔设置问题
为什么我需要这么⼀款看上去没啥⽤的插件呢?因为在实际的爬⾍任务中碰到⼀个问题,要爬取的⽹站是个国外的⽹站,⽽现在稍具规模的⽹站都喜欢搞国际化,就是针对不同国家的访客显⽰不同的语⾔,理论上这样对⽤户更友好(实际上国际化如果做得不够好的话会有点奇怪...),这样就不⽤让⽤户再去
翻译软件翻译了,⽽且国际化是⼈设置的理论上要⽐翻译软件更好⼀些。
那国际化是通过什么实现的呢?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=顶
<_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⼀般都是浏览器设置的,浏览器更知道当前的系统环境应该是哪种语
⾔在安装时就可以⾃动设置为正确的语⾔,然后⼜提供了修改途径来让⽤户可以⼿动修正,这种⽅式更可靠。
2.2 借助ModHeader来检测必须要设置的请求头
很多⽹站都会有简单的反爬措施,⽐较常见的是加密参数,加密参数的其中⼀种形式是使⽤⾃定义的请求头来设置,⽐如下⾯这个请求头:
:authority: api.joom
: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 SEV0001MTU0MTc0ODc0N3xoSjZTMmF4TFp0MVZrQkgwcXc4X3cwVGRiX0dseFM0RjRVZS04Nk1Benl1X01YSHZKb3loSEFYT2IzQUVXOX origin: www.joom
referer: www.joom/en/products/1498834929187697429-213-1-709-71790600?context=%7B%22type%22%3A%22product%22%2C%22value%22%3A% 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看上去很可疑,怎么快速确定哪个请求头是必须要设置的呢?我们可不想花费太多时间在⾮必要参数上,
当然可以写点代码⼀点⼀点测试出来,好,现在来将难度再升级⼀下,假如这些参数都是动态⽣成的,每次都不⼀样,即使将它们的值复制到程序中
也不能⽤,也就是要在程序中模拟必须要先搞清楚这些值是如何来的,可是⼜不想花半天时间好不容易搞清楚⼀个请求头怎么来的突然发现这个请求
头不设置也可以,只好在⼼⾥默默流泪... (╥╯^╰╥)
这个时候可以借助ModHeader在浏览器中将怀疑的请求头的值设置为空,即模拟不传递此请求头的⾏为,然后刷新⼀下看看会发⽣什么事,⽐如上
⾯的那个例⼦,页⾯地址:。
⾸先屏蔽掉x-api-token这个请求头:chrome浏览器是什么浏览器图标
然后刷新⽹页,观察请求数据的那个ajax请求的请求头:
x-api-token这个请求头没有设置依然返回了数据,说明它应该不是必要参数,不必再在这上⾯花费⼒⽓了。
再来试⼀下authorization:
清除缓存刷新:
不传这个参数页⾯直接挂掉了,连去请求商品详情的ajax请求都没有发送,说明这个参数应该是必须的,可使⽤同样⽅法排查其它请求头。总结:使⽤ModHeader快速确定哪些请求头是必须的,提⾼分析⽬标⽹站的效率。
.
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论