一、Selenium
该问题好久之前就遇到了,直接使用 selenium 解决
谷歌浏览器解决方法:
实际上是这个在起作用,就是别人通过JS知道你是爬虫了,但是谷歌设置之后可以访问,但是页面跳转就没用了,有哪位有办法可以分享一下?
driver.execute_cdp_cmd("Page.addScriptToEvaluateOnNewDocument", {
"source": """
Object.defineProperty(navigator, 'webdriver', {
get: () => undefined
})
"""
})
火狐浏览器解决办法:(终极方法)
火狐直接不需要设置,直接访问,跳转页面也无碍
二、Scrapy
现在由于要使用 scrapy,所以在一般网站使用 splash,但是这种网站 splash 就很无奈了,只能使用 scrapy 同时配合 selenium,但是问题来了,你可以访问但是无法下载啊,下载链接复制了通过下载器也是下载不了,只能在浏览器里面点击下载
【分析】
1、网上能说到这个问题的都是在说,请求参数里面有 If-None-Match 字段,但是我看了没有,但是他们有一点说的是对的,就是确实问题出在了请求参数上面,毕竟 412 状态码就是前提条件失败嘛。
2、通过对比下载请求,每次只有 cookie 不一样,因此大概率为 cookie。
3、通过浏览器内删除所有 cookie,再次点击下载链接发出请求,查看 cookie 新增了哪些,这是通过浏览器查看的 cookie,示例如下:
4、观察发现这三个字段必定会出来,其他字段不影响下载的请求。
5、经测试,只有前两个为必须,拼接好后通过 requests 携带 cookies 进行访问,下载文件,值得注意的是 cookie 的寿命都被设置的很短。
6、scrapy 中也使用 selenium 进行配合,然后在要下载的时候,通过 pipline 中的 process_item 中的 spider,去获得 cookie ,和 selenium 操作一样(需要正确设置selenium),再操作一下传给 requests 进行下载。
【示例】
if spider.name in ['']:
# cookies:在这里获取修改成自己需要的cookie
cookie = spider.driver.get_cookies()
cookies = {}
for i in cookie:
cookies[f"{i.get('name')}"] = f"{i.get('value')}"
resp = requests.get(url=item['file_url'], headers=headers,cookies=cookies)
else:
resp = requests.get(url=item['file_url'], headers=headers)
【总结】
话一大堆,是因为其他人都没有一个解决掉问题的,起码没搜到。
总体上很简单,其实就是缺少了参数,连续发两次请求之后定位一下不同的地方,这个地方就是导致 412 的位置。
三、拓展
后面我再去下载的时候,由于会重定向非常多次,并且下载也会有比较大的失败率,所以最后选择了,到 pipeline 的时候新打开一个 selenium 然后去下载文件,当然了,我是指定了下载位置的,需要这段教程说明的可以留言再出,我用的是火狐浏览器