這幾天你是不是等快遞等的花兒都謝了?用爬蟲查雙十一的快遞!
少年們,你們雙十一剁手了嗎?現在收到快遞了嗎?現在是不是痛苦萬分,天天過著吃土的日子啊?
吃土不要緊,只要有本事,就輪不到吃土。鏟屎官今天就給大家帶來一個騷氣的爬蟲操作,可以讓你查詢自己的快遞狀態。
這個就是 Splash 和 scrapy-splash。Splash是一個javascript渲染服務。它是一個帶有HTTP API的輕量級Web瀏覽器,使用Twisted和QT5在Python 3中實現。所以,如果使用 Splash 的話,需要一臺伺服器做支撐。而 scrapy-splash 則是一個Python庫,能夠在 Scrapy 框架裡面使用 Splash 。
今天,鏟屎官就來拿這兩個東西,來個你們捯飭捯飭如何能夠優雅的查詢到你的快遞訂單情況。
Splash初探
Splash在前面說了,是一個 JavaScript 渲染服務,所以,我們如果要玩 Splash,就需要一臺機器作為伺服器來支撐。哪裡有伺服器呢?你可以有兩個選擇:
- 使用自己的機器作為伺服器來執行
- 用你雙十一購買的阿里雲伺服器或者騰訊雲伺服器來做操作(推薦)
插播一則小福利:
雖然已經過了雙十一了,但是,如果你還沒有云伺服器的話,可以通過下面的兩個連結來領取價值千元的雲伺服器優惠券,原價300多的伺服器,一年用了優惠券只要100多,不到200。超級實惠,數量有限,機會不多,大家要抓緊。
阿里雲(最高¥1888雲產品通用代金券):
https://promotion.aliyun.com/ntms/yunparter/invite.html?userCode=nrkmbo9q
騰訊雲(總價值高達2775元代金券):
https://cloud.tencent.com/redirect.php?redirect=1025&cps_key=b351b2fc50b15866ff9d19b58a5df0f5
鏟屎官這裡,就給大家演示在阿里雲伺服器上面是怎麼操作的。因為雙十一的時候,阿里雲的伺服器那是真的便宜啊。如果你那個時候還在猶豫,沒有買,那麼對不起,你的猶豫耽誤了你上車,現在的伺服器如果領券了也要將近200一年。所以,在機遇面前,人要當機立斷,千萬不能猶豫。如果你沒有伺服器,那麼本地安裝步驟也基本一致。如果有什麼細微不一樣的地方,安裝過程請簡單百度一下,網路一堆答案。
進群:548377875 即可獲取小編精心準備的資料哦!
如果要裝Splash,我們首先需要在 Linux伺服器上面安裝 Docker。
大家別慌,別聽到 Docker 就覺得這個東西好高大上,好神祕。其實,我們這裡使用 Docker 就是為了兩點:一是安裝 Splash;二是執行 Splash 服務。
我拿來講解的阿里雲伺服器上面安裝的是 CentOS 7.4 系統。
首先,通過命令 $ docker --version 來檢測你的伺服器上之前有沒有安裝過 Docker。
如果沒有安裝過,那麼 Docker 要求 CentOS 系統的核心版本高於 3.10 ,所以前提條件來驗證你的CentOS 版本是否支援 Docker 。輸入以下命令即可檢視:
1$ uname -r
我的伺服器出現的結果如下:
顯示的結果是大於3.10,可以安裝。
接著,我們需要升級一下 yum 和開始安裝,這個簡單,依次輸入下面的命令就可以:
1# 升級 yum 2$ yum update 3 4# 安裝需要的軟體包依賴 5$ yum install -y yum-utils device-mapper-persistent-data lvm2 6 7# 設定yum源 8$ yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo 9 10# 安裝docker(由於repo中預設只開啟stable倉庫,故這裡安裝的是最新穩定版) 11$ yum install docker-ce 12 13# 啟動並加入開機啟動 14$ systemctl start docker 15$ systemctl enable docker
如果一切執行完畢,那麼就說明 Docker 安裝成功並且已經執行起來了,通過命令 $ docker version 來檢視是否成功:
有client和service兩部分表示docker安裝啟動都成功了。
接下來,我們來安裝 Splash 。安裝炒雞簡單,就只需要輸入以下命令就可以:
1$ docker pull scrapinghub/splash
這個安裝過程時間有點長,在這期間,可以去阿里雲或者騰訊雲的雲伺服器控制檯,去吧相關安全組介面開啟。
安裝完成之後,長這個樣子:
由於 Splash 啟動埠預設是 8050,所以我們得需要在安全組裡面,開啟這個端口才可以。
如果你是阿里雲,請參考一下操作步驟:
如果你是騰訊雲,請參考一下操作步驟:
接著,我們通過命令來在你的伺服器上啟動 Splash。
1$ docker run -p 8050:8050 scrapinghub/splash
這個時候,Splash服務就成功啟動了。如果想檢視Splash服務啟動是否成功,只需要在你的瀏覽器裡面去訪問你伺服器的8050埠就可以。瀏覽器裡面輸入 http://<你伺服器的公網IP地址>:8050/,如果是本地執行,則輸入http://localhost:8050/。這個地址可以開啟,頁面長這個樣子:
如果這個頁面出現,那麼就代表 Splash 服務成功啟動。這個頁面的作用,其實你可以在一定程度上面起到除錯的作用。注意右邊,有一個白色的輸入框,還有一個大的黑色的輸入框。白色的輸入框是用來輸入網頁地址的;而黑色的框則是用LUA語言來編寫Splash指令碼的。為什麼會有些指令碼語言的地方?因為 Splash 是一個 JavaScript 的渲染服務,在這其中,你可能需要模擬一些使用者的行為,但是模擬行為就是通過程式碼來實現的,所以需要寫一些程式碼。
我們可以先來嘗試的玩一下,在白色輸入地址的框框裡面,輸入百度的地址:https://www.baidu.com/ ,然後點選 Redner me!:
這個頁面是不是很酷炫?這裡主要有三個成分:最上面是頁面渲染之後的圖片,中間是HAR資訊,最下面則是頁面渲染之後的html資訊。接著我們看一下 Script 裡面有什麼東西:
這裡面相當簡單,相當於 Hello World。我在這裡給大家簡單講解一下:
首先是有一個 Main 函式,這個就是 Splash 的入口函式,裡面有兩個引數,一個是splash,另一個是 args。
接著是 splash:go() 方法,引數是一個url,這個方法的目的就是指定服務跳轉到這個url。
然後是 splash:wait() 方法,是讓頁面等待xx秒。因為有些渲染需要時間,所以這裡要等待。
最後就是返回方法,我們看到返回三部分,分別對應的是 image, har 和 html。
結構非常清晰,如果有想更多瞭解其他方法的同學,可以參考這個連結裡面的內容,方法寫的非常詳細:
https://cuiqingcai.com/5638.html
Scrapy-splash爬蟲查詢快遞
這裡主要講解 Scrapy-splash 的使用,如果對 Scrapy 爬蟲框架不是很瞭解的話,可以閱讀下面這篇鏟屎官的文章,做一下了解:
PeekpaHub全棧開發教程【節選內容】
首先,我們得在本地的機器上面安裝 scrapy-splash:
1$ pip install scrapy-splash
接著,我們需要建立一個 Scrapy 工程,這裡,我們需要在 settings.py 檔案裡面修改一些東西,我們需要把 Splash 伺服器的介面配置上去,同事還需要新增splash的中間層。
1SPLASH_URL = 'http://<你Splash伺服器的IP地址,如果是本地的,則是localhost>:8050' 2 3SPIDER_MIDDLEWARES = { 4 'scrapy_splash.SplashDeduplicateArgsMiddleware': 100, 5} 6 7DOWNLOADER_MIDDLEWARES = { 8 'scrapy_splash.SplashCookiesMiddleware': 723, 9 'scrapy_splash.SplashMiddleware': 725, 10 'scrapy.downloadermiddlewares.httpcompression.HttpCompressionMiddleware': 810 11}
接著,我們需要修改我們的爬蟲檔案。我們這裡是需要爬去百度頁面的快遞資訊,比如,我的訂單號是“71421570320700”,然後在百度裡面一輸入這個號碼,會自顯示出來訂單號資訊:
資訊就是這樣,我們可以通過 Chrome 瀏覽器的開發者工具,來看一下網頁原始碼裡面,快遞資訊對應的地方結構是什麼:
看到這個是一個 div 標籤,它裡面的特徵是 class="op_express_delivery_timeline_info",所以,我們的爬蟲寫成這樣:
1import scrapy 2from bs4 import BeautifulSoup 3from scrapy_splash import SplashRequest 4 5script = """ 6 function main(splash, args) 7 assert(splash:go(args.url)) 8 assert(splash:wait(args.wait)) 9 js = string.format("document.querySelector('#kw').value=%s;document.querySelector('#su').click()", args.cargoNo) 10 splash:evaljs(js) 11 assert(splash:wait(args.wait)) 12 return splash:html() 13 end 14 """ 15 16class JavspiderSpider(scrapy.Spider): 17 name = 'JavSpider' 18 allowed_domains = ['javpop.com'] 19 20 # start request 21 def start_requests(self): 22 urlBaidu = "https://www.baidu.com/" 23 yield SplashRequest(urlBaidu, callback=self.parse_page, endpoint='execute', 24 args={'lua_source': script, 'cargoNo': '71421570320700', 'wait': 1}) 25 26 # parse the html content 27 def parse_page(self, response): 28 content = response.body 29 soup = BeautifulSoup(content, "html.parser") 30 div_list = soup.find_all('div', attrs={"class": "op_express_delivery_timeline_info"}) 31 print('=' * 40) 32 for item in div_list: 33 print(item.text) 34 print('=' * 40)
這裡的爬蟲寫的很簡單,只是為了給大家展示一下 Scrapy-splash 的使用。簡單的說一下爬蟲的結構:
首先是有 script 變數,這個變數就是我們在之前提到的黑色框框裡面的Lua指令碼。這裡的程式碼邏輯就是,先去百度頁面,然後在搜尋框裡面輸入訂單號,然後點選搜尋按鈕。
然後在 start_request() 方法裡面,我們呼叫的是 SplashRequest() 方法。我們需要調的是scrapy-splash的 SplashRequest,而不是之前的 scrapy 的 Request。
最後就是 args 裡面,我們傳入的引數有這麼幾個,這幾個引數對應的就是 script 裡面的變數。
其他都是標準的爬蟲流程,比如用 BeautifulSoup 來解析 html 等。
如果這個時候爬蟲執行,則可以看到控制檯輸出了結果:
我們看到,這個快遞資訊已經答應出來了。我們的教學任務就此完成。
後續
這個可以再擴充套件一下,比如把快遞資訊封裝起來啊,儲存起來啊,玩法有很多,大家可以自行發揮。