前幾天有個朋友託我幫忙爬一個網站,第一次打開那個網站時,我去,它居然就要驗證碼,不過當時是想加幾個header應該就能解決,不過事實證實我仍是錯了。接下來將記錄下爬蟲中遇到的一些坑以及解決辦法。javascript
目標網站:AVADA – Avada Commerce
使用了Cloudflare的cdn服務,並且Cloudflare又和百度有合做,因此咱們的訪問異常時,就會被百度的雲加速服務給攔截下來。css
原本是準備用比較拿手的java寫這次爬蟲,java請求返回的內容老是出現一些亂碼的問題。已經設置爲utf-8方式而且像gzip、br等解壓縮都嘗試了,稍微好點的狀況只有body標籤內的內容爲亂碼,糟糕的狀況就是整個返回的內容皆爲亂碼。後來就用python試了試,亂碼問題直接沒了,有點迷!html
以前用python解決亂碼問題後,緊接着又出現的就是訪問須要驗證碼了。當時我是瀏覽器裏訪問不須要驗證碼,但python訪問無論如何,一直出現百度雲加速的驗證碼認證。出現這種狀況,個人第一反應是python中是否是少了某些關鍵頭部,因而將瀏覽器中的header帶到python中一 一去試,但並無起到啥做用。這裏我就賊納悶了,究竟爲甚嗎???後來才忽然想起來我瀏覽器走了代理,因而我乾脆給電腦設置了個全局代理,而後用python繼續訪問,讓人感動的一幕發生了-----> 命令行中返回了目標網站的頁面源代碼!這時我才察覺,個人本地IP已經進入了目標網站的黑名單 。到這裏,驗證碼也就繞過了。java
在把前面的目標網站的頁面下載到本地後,而後用瀏覽器打開該文件,瀏覽器會加載頁面中的一些圖片css還有js等資源文件,其中有個js會檢測當前頁面url中的協議是不是https,若是不是,將重定向至對應的https協議的頁面。這裏顯然,咱們打開的本地文件url是文件的目錄,不是以https開始的。
好比火狐瀏覽器中打開目標文件,地址欄的url以下python
file:///C:/Users/Asche/vscode/Shopify/temp/Customers/How%20to%20add%20or%20edit%20a%20customer%E2%80%99s%20address.html
被重定向後的url以下瀏覽器
https://c/Users/Asche/vscode/Shopify/temp/Customers/How%20to%20add%20or%20edit%20a%20customer%E2%80%99s%20address.html
顯然,重定向後的頁面是不存在的。固然,咱們也能夠在頁面重定向前手動取消重定向的請求,不過這樣畢竟體驗很差,因此繼續想辦法解決重定向問題。
因而,準備尋找起重定向做用的·js代碼,瀏覽一番渲染後的頁面源代碼,發如今body標籤結束前,多了這樣一段代碼:安全
<script type="text/javascript" id="">"https:"!=location.protocol&&(location.href="https:"+window.location.href.substring(window.location.protocol.length));</script>
並且這段代碼在最初的頁面內是沒有的,說明是被別的js動態加載進來的。因此我就選擇其中的一段代碼‘location.protocol‘,在其他幾個可疑的js文件內搜索,遺憾的是沒有找到。
另外原本想使用js的debug功能,奈何一到dubug頁面,瀏覽器就未響應!!!
最後沒有辦法,我就直接在目標文件上選擇性的註釋js引入,可疑的js文件都被註釋掉了,卻發現任然存在重定向!!!最後,只剩下一個google相關的js,把那個js註釋掉,重定向終於消失了!那段js代碼大概以下:async
<script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start': new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0], j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src= 'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f); })(window,document,'script','dataLayer','GTM-NPVH4QZ');</script>
原本覺得這段代碼就像google分析那樣的一些沒啥影響的Google服務,結果卻讓人有點意外!多是出於安全的考慮把。
到這裏,重定向也解決!網站
import requests import os from bs4 import BeautifulSoup # Author: Asche # date: 2019年7月6日 print('Shopify start...') BASE_URL = 'https://avada.io' headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36', 'Cookie': '__cfduid=db73a1a3b63a54e86f435f615f5ec37791562300679; _ga=GA1.2.1048718546.1562300686; _gid=GA1.2.312498482.1562300686', 'Accept': '*/*', 'Accept-Encoding': 'gzip', 'Accept-Language': 'en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7,mt;q=0.6'} def getHtml(url): req = requests.get(url, headers=headers) return req.text def saveFile(name, dir, content): folder = os.path.exists(dir) if not folder: os.mkdir(dir) with open( dir + '/' + name.replace('/', '_') + '.html', 'w', encoding='utf-8') as f: f.write(content) def crawlSubpage(url, dir): subPage = requests.get(url, headers=headers) # print(strHome.headers) soup = BeautifulSoup(subPage.content, 'lxml') print(soup.title) titles = soup.select('div.collection a') for title in titles: print(title.text, title['href']) saveFile(title.text, dir, getHtml(title['href'])) strHome = requests.get(BASE_URL, headers=headers) # print(strHome.text) print(strHome.headers) soup = BeautifulSoup(strHome.content, 'lxml') # print(soup.prettify) print(soup.title) titles = soup.select('h3.header a') for title in titles: print(title.text, title['href']) crawlSubpage(title['href'], title.text)