一、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 然后去下載文件,當然了,我是指定了下載位置的,需要這段教程說明的可以留言再出,我用的是火狐瀏覽器