大數據的時代,網絡爬蟲已經成爲了獲取數據的一個重要手段。前端
但要學習好爬蟲並無那麼簡單。首先知識點和方向實在是太多了,它關係到了計算機網絡、編程基礎、前端開發、後端開發、App 開發與逆向、網絡安全、數據庫、運維、機器學習、數據分析等各個方向的內容,它像一張大網同樣把如今一些主流的技術棧都鏈接在了一塊兒。正由於涵蓋的方向多,所以學習的東西也很是零散和雜亂,不少初學者搞不清楚究竟要學習哪些知識,學習過程當中遇到反爬也不知道用什麼方法來解決,本篇咱們來作一些概括和總結。web
一些最基本的網站,每每不帶任何反爬措施。好比某個博客站點,咱們要爬全站的話就順着列表頁爬到文章頁,再把文章的時間、做者、正文等信息爬下來就能夠了。正則表達式
那代碼怎麼寫呢?用 Python 的 requests 等庫就夠了,寫一個基本的邏輯,順着把一篇篇文章的源碼獲取下來,解析的話用 XPath、BeautifulSoup、PyQuery 或者正則表達式,或者粗暴的字符串匹配把想要的內容摳出來,再加個文本寫入存下來就完事了。算法
代碼很簡單,就幾個方法調用。邏輯很簡單,幾個循環加存儲。最後就能看到一篇篇文章就被咱們存到本身的電腦裏面了。固然有的同窗可能不太會寫代碼或者都懶得寫,那麼利用基本的可視化爬取工具,如某爪魚、某裔採集器也能經過可視化點選的方式把數據爬下來。數據庫
若是存儲方面稍微擴展一下的話,能夠對接上 MySQL、MongoDB、Elasticsearch、Kafka 等等來保存數據,實現持久化存儲。之後查詢或者操做會更方便。編程
反正,無論效率如何,一個徹底沒有反爬的網站用最最基本的方式就搞定了。網頁爬蟲
到這裏,你就說你會爬蟲了嗎?不,還差的遠呢。後端
對於初學者想更輕鬆的學好Python開發技術,Python爬蟲,Python大數據分析,人工智能等技術,這裏給你們分享一套系統教學資源,加一下我建的Python技術的學習裙;七八四七五八二一四,一塊兒學習。有相關開發工具,學習教程,天天還有專業的老司機在線直播分享知識與技術答疑解惑!
隨着互聯網的發展,前端技術也在不斷變化,數據的加載方式也再也不是單純的服務端渲染了。如今你能夠看到不少網站的數據可能都是經過接口的形式傳輸的,或者即便不是接口那也是一些 JSON 的數據,而後通過 JavaScript 渲染得出來的。瀏覽器
這時候,你要再用 requests 來爬那就不頂用了,由於 requests 爬下來的源碼是服務端渲染獲得的,瀏覽器看到頁面的和 requests 獲取的結果是不同的。真正的數據是通過 JavaScript 執行的出來的,數據來源多是 Ajax,也多是頁面裏的某些 Data,也多是一些 ifame 頁面等等,不過大多數狀況下多是 Ajax 接口獲取的。安全
因此不少狀況下須要分析 Ajax,知道這些接口的調用方式以後再用程序來模擬。可是有些接口帶着加密參數,好比 token、sign 等等,又很差模擬,咋整呢?
一種方法就是去分析網站的 JavaScript 邏輯,死摳裏面的代碼,揪出來這些參數是怎麼構造的,找出思路來了以後再用爬蟲模擬或重寫就好了。若是你解出來了,那麼直接模擬的方式效率會高很是多,這裏面就須要一些 JavaScript 基礎了,固然有些網站加密邏輯作的太牛逼了,你可能花一個星期也解不出來,最後放棄了。
那這樣解不出來或者不想解,那咋辦呢?這時候能夠有一種簡單粗暴的方法就是直接用模擬瀏覽器的方式來爬取,好比用 Puppeteer、Pyppeteer、Selenium、Splash 等,這樣爬取到的源代碼就是真正的網頁代碼,數據天然就好提取了,同時也就繞過度析 Ajax 和一些 JavaScript 邏輯的過程。這種方式就作到了可見便可爬,難度也不大,同時模擬了瀏覽器,也不太會有一些法律方面的問題。
但其實後面的這種方法也會遇到各類反爬的狀況,如今不少網站都會去識別 webdriver,看到你是用的 Selenium 等工具,直接幹掉或不返回數據,因此你碰到這種網站還得來專門解一下這個問題。
上面的狀況若是用單線程的爬蟲來模擬是比較簡單的,可是有個問題就是速度慢啊。
爬蟲是 IO 密集型的任務,因此可能大多數狀況下都在等待網絡的響應,若是網絡響應速度慢,那就得一直等着。但這個空餘的時間其實可讓 CPU 去作更多事情。那怎麼辦呢?多開點線程吧。
因此這時候咱們就能夠在某些場景下加上多進程、多線程,雖說多線程有 GIL 鎖,但對於爬蟲來講其實影響沒那麼大,因此用上多進程、多線程均可以成倍地提升爬取速度,對應的庫就有 threading、multiprocessing 了。
異步協程就更牛逼了,用 aiohttp、gevent、tornado 等等的基本上你想搞多少併發就搞多少併發,可是仍是悠着點,別把人家網站搞掛了。
總之,用上這幾個,爬蟲速度就提上來了。
但速度提上來了不必定是好事,反爬接着確定就要來了,封你 IP、封你帳號、彈驗證碼、返回假數據,因此有時候龜速爬彷佛也是個解決辦法?
多線程、多進程、協程都能加速,但終究仍是單機的爬蟲。要真正作到規模化,還得來靠分佈式爬蟲來搞。
分佈式的核心是什麼?資源共享。好比爬取隊列共享、去重指紋共享等等。
咱們可使用一些基礎的隊列或組件來實現分佈式,好比 RabbitMQ、Celery、Kafka、Redis 等等,但通過不少人的嘗試,本身去實現一個分佈式爬蟲,性能和擴展性總會出現一些問題,固然特別牛逼的除外哈。很多企業內部其實也有本身開發的一套分佈式爬蟲,和業務更緊密,這種固然是最好了。
如今主流的 Python 分佈式爬蟲仍是基於 Scrapy 的,對接 Scrapy-Redis、Scrapy-Redis-BloomFilter 或者用 Scrapy-Cluster 等等,他們都是基於 Redis 來共享爬取隊列的,總會多多少少遇到一些內存的問題。因此一些人也考慮對接到了其餘的消息隊列上面,好比 RabbitMQ、Kafka 等等,解決一些問題,效率也不差。
總之,要提升爬取效率,分佈式仍是必需要掌握的。
爬蟲不免遇到反爬,驗證碼就是其中之一。要會反爬,那首先就要會解驗證碼。
如今你能夠看到不少網站都會有各類各樣的驗證碼了,好比最簡單的圖形驗證碼,要是驗證碼的文字規整的話,OCR 過一遍或者基本的模型庫都能識別,不想搞這個的話能夠直接去對接個打碼平臺來搞,準確率仍是有的。
然而你可能如今都見不到什麼圖形驗證碼了,都是一些行爲驗證碼,如某驗、某盾等等,國外也有不少,好比 reCaptcha 等等。一些稍微簡單一點的,好比滑動的,你能夠找點辦法識別缺口,好比圖像處理比對、深度學習識別都是能夠的。軌跡呢本身寫個模擬正常人行爲的,加點抖動之類的。有了軌跡以後咋模擬呢,若是你牛逼,那麼能夠直接去分析驗證碼的 JavaScript 邏輯,把軌跡數據錄入,那就能獲得裏面的一些加密參數,直接拿着這些參數放到表單或接口裏面就能直接用了。固然也能夠用模擬瀏覽器的方式來拖動,也能經過必定的方式拿到加密參數,或者直接用模擬瀏覽器的方式把登陸一塊兒作了,拿着 Cookies 來爬也行。
固然拖動只是一種驗證碼,還有文字點選、邏輯推理等,要是真不想搞,能夠找打碼平臺來解出來再模擬,但畢竟花錢的,一些高手就會選擇本身訓練深度學習相關的模型,收集數據、標註、訓練,針對不一樣的業務訓練不一樣的模型。這樣有了核心技術,也不用再去花錢找打碼平臺了,再研究下驗證碼的邏輯模擬一下,加密參數就能解出來了。不過有的驗證碼可貴很,有的我也沒搞定。
固然有些驗證碼多是請求過於頻繁而彈出來的,這種若是換個 IP 什麼的也能解。
封 IP 也是個使人頭疼的事,行之有效的方法就是換代理了。
代理不少種,市面上免費的,收費的太多太多了。
首先能夠把市面上免費的代理用起來,本身搭建一個代理池,收集如今全網全部的免費代理,而後加一個測試器一直不斷測試,測試的網址能夠改爲你要爬的網址。這樣測試經過的通常都能直接拿來爬你的目標網站。
付費代理也是同樣,不少商家提供了代理提取接口,請求一下就能獲取幾十幾百個代理,咱們能夠一樣把它們接入到代理池裏面。但這個代理也分各類套餐,什麼開放代理、獨享代理等等的質量和被封的概率也是不同的。
有的商家還利用隧道技術搭了代理,這樣代理的地址和端口咱們是不知道的,代理池是由他們來維護的,好比某布雲,這樣用起來更省心一些,可是可控性就差一些。
還有更穩定的代理,好比撥號代理、蜂窩代理等等,接入成本會高一些,可是必定程度上也能解決一些封 IP 的問題。
不過這些背後也不簡單,爲啥一個好好的高匿代理就是莫名其妙爬不了,背後的一些事就很少講了。
有些信息須要模擬登陸才能爬嘛,若是爬的過快,人家網站直接把你的帳號封禁了,就啥都沒得說了。好比爬公衆號的,人家把你 WX 號封了,那就全完了。
一種解決方法固然就是放慢頻率,控制下節奏。
還有種方法就是看看別的終端,好比手機頁、App 頁、wap 頁,看看有沒有能繞過登陸的法子。
另外比較好的方法,那就是分流。若是你號足夠多,建一個池子,好比 Cookies 池、Token 池、Sign 池反正無論什麼池吧,多個帳號跑出來的 Cookies、Token 都放到這個池子裏面,用的時候隨機從裏面拿一個。若是你想保證爬取效率不變,那麼 100 個帳號相比 20 個帳號,對於每一個帳號對應的 Cookies、Token 的取用頻率就變成原來的了 1/5,那麼被封的機率也就隨之下降了。
上面說的是幾種比較主流的反爬,固然還有很是多奇葩的反爬。好比返回假數據、返回圖片化數據、返回亂序數據、返回罵人的數據、返回求饒的數據,那都具體狀況看着辦吧。
這些反爬也得當心點,以前見過一個反爬直接返回 rm -rf /
的也不是沒有,你要是正好有個腳本模擬執行返回結果,後果本身想象哈。
說到重頭了。隨着前端技術的進步和網站反爬意識的加強,不少網站選擇在前端上下功夫,那就是在前端對一些邏輯或代碼進行加密或混淆。固然這不只僅是爲了保護前端的代碼不被輕易盜取,更重要的是反爬。好比不少 Ajax 接口都會帶着一些參數,好比 sign、token 等等,這些前文也講過了。這種數據咱們能夠用前文所說的 Selenium 等方式來爬,但總歸來講效率過低了,畢竟它模擬的是網頁渲染的整個過程,而真實的數據可能僅僅就藏在一個小接口裏。
若是咱們可以把一些接口的參數真正找出其中的邏輯,用代碼來模擬執行,那效率就會有成倍的提高,並且還能在必定程度上規避上述的反爬現象。
但問題是什麼?難啊。
Webpack 是一方面,前端代碼都被壓縮和轉碼成一些 bundle 文件,一些變量的含義已經丟失,很差還原。而後一些網站再加上一些 obfuscator 的機制,把前端代碼變成你徹底看不懂的東西,好比字符串拆散打亂、變量十六進制化、控制流扁平化、無限 debug、控制檯禁用等等,前端的代碼和邏輯已經面目全非。有的用 WebAssembly 等技術把前端核心邏輯直接編譯,那就只能慢慢摳了,雖說有些有必定的技巧,可是總歸來講仍是會花費不少時間。但一旦解出來了,那就萬事大吉了。怎麼說?就像奧賽題同樣,解出來昇天,解不出來 GG。
不少公司招聘爬蟲工程師都會問有沒有 JavaScript 逆向基礎,破解過哪些網站,好比某寶、某多、某條等等,解出來某個他們須要的可能就直接錄用你。每家網站的邏輯都不同,難度也不同。
固然爬蟲不只僅是網頁爬蟲了,隨着互聯網時代的發展,如今愈來愈多的公司都選擇將數據放到 App 上面,甚至有些公司只有 App 沒有網站。因此數據只能經過 App 來爬。
咋爬呢?基本的就是抓包工具了,Charles、Fiddler 一把梭,抓到接口以後,直接拿來模擬就好了。
若是接口有加密參數怎麼辦呢?一種方法你能夠邊爬邊處理,好比 mitmproxy 直接監聽接口數據。另外一方面你能夠走 Hook,好比上 Xposed 也能夠拿到。
那爬的時候又怎麼實現自動化呢?總不能拿手來戳吧。其實工具也多,安卓原生的 adb 工具也行,Appium 如今已是比較主流的方案了,固然還有其餘的某精靈都是能夠實現的。
最後,有的時候可能真的就不想走自動化的流程,我就想把裏面的一些接口邏輯摳出來,那就得搞逆向了,IDA Pro、jdax、FRIDA 等工具就派上用場了,固然這個過程和 JavaScript 逆向同樣很痛苦,甚至可能得讀彙編指令。搞一個案例掉一把頭髮也不是不可能的。
上面的這一通,都搞熟了,恭喜你已經超過了百分之八九十的爬蟲玩家了,固然專門搞 JavaScript 逆向、App 逆向的都是站在食物鏈頂端的男人,這種嚴格來講已經不算爬蟲範疇了,這種神咱們就不算在裏面了,反正我不是。
除了上面的一些技能,在一些場合下,咱們可能也須要結合一些機器學習的技術,讓咱們的爬蟲變得更智能起來。
好比如今不少博客、新聞文章,其頁面結構類似度比較高,要提取的信息也比較相似。
好比如何區分一個頁面是索引頁仍是詳情頁?如何提取詳情頁的文章連接?如何解析文章頁的頁面內容?這些其實都是能夠經過一些算法來計算出來的。
因此,一些智能解析技術也營運而生,好比提取詳情頁,一位朋友寫的 GeneralNewsExtractor 表現就很是好。
假如說我來了一個需求,我要爬取一萬個新聞網站數據,要一個個寫 XPath 嗎?寫死我吧。若是有了智能化解析技術,在容忍必定錯誤的條件下,完成這個就是分分鐘的事情。
總之,若是咱們能把這一塊也學會了,咱們的爬蟲技術就會如虎添翼。
這塊也是一個重頭戲。爬蟲和運維也是息息相關。
好比寫完一個爬蟲,怎樣去快速部署到 100 臺主機上跑起來。
好比怎麼靈活地監控每一個爬蟲的運行狀態。
好比爬蟲有處代碼改動,如何去快速更新。
好比怎樣監控一些爬蟲的佔用內存、消耗的 CPU 情況。
好比怎樣科學地控制爬蟲的定時運行、
好比爬蟲出現了問題,怎樣能及時收到通知,怎樣設置科學的報警機制。
這裏面,部署你們各有各的方法,好比用 Ansible 固然能夠。若是用 Scrapy 的話有 Scrapyd,而後配合上一些管理工具也能完成一些監控和定時任務。不過我如今用的更可能是仍是 Docker + Kubernetes,再加上 DevOps 一套,好比 GitHub Actions、Azure Pipelines、Jenkins 等等,快速實現分發和部署。
定時任務你們有的用 crontab,有的用 apscheduler,有的用管理工具,有的用 Kubernetes,個人話用 Kubernetes 就多一些了,定時任務也是很好實現。
至於監控的話,也有不少,專門的一些爬蟲管理工具自帶了一些監控和報警功能。一些雲服務也帶了一些監控的功能。我用的是 Kubernetes + Prometheus + Grafana,什麼 CPU、內存、運行狀態,一目瞭然,報警機制在 Grafana 裏面配一下也很方便,支持 Webhook、郵件甚至某釘。
數據的存儲和監控,用 Kafka、Elasticsearch 我的感受也挺方便的,我主要用的是後者,而後再和 Grafana 配合起來,數據爬取量、爬取速度等等監控也都一目瞭然。
至此,爬蟲的一些涵蓋的知識點也就差很少了,怎麼樣,梳理一下,是否是計算機網絡、編程基礎、前端開發、後端開發、App 開發與逆向、網絡安全、數據庫、運維、機器學習都涵蓋到了?上面總結的能夠算是從爬蟲小白到爬蟲高手的路徑了,裏面每一個方向其實可研究的點很是多,每一個點作精了,都會很是了不得。
爬蟲每每學着學着,就成爲了一名全棧工程師或者全乾工程師,由於你可能真的啥都會了。可是沒辦法啊,都是被爬蟲逼的啊,若是不是生活所困,誰願意一身才華呢?