人生苦短,我用 Pythonhtml
前文傳送門:python
小白學 Python 爬蟲(2):前置準備(一)基本類庫的安裝github
小白學 Python 爬蟲(3):前置準備(二)Linux基礎入門shell
小白學 Python 爬蟲(4):前置準備(三)Docker基礎入門數據庫
小白學 Python 爬蟲(5):前置準備(四)數據庫基礎json
小白學 Python 爬蟲(6):前置準備(五)爬蟲框架的安裝服務器
小白學 Python 爬蟲(7):HTTP 基礎cookie
小白學 Python 爬蟲(10):Session 和 Cookies
小白學 Python 爬蟲(11):urllib 基礎使用(一)
小白學 Python 爬蟲(12):urllib 基礎使用(二)
小白學 Python 爬蟲(13):urllib 基礎使用(三)
小白學 Python 爬蟲(14):urllib 基礎使用(四)
小白學 Python 爬蟲(15):urllib 基礎使用(五)
小白學 Python 爬蟲(16):urllib 實戰之爬取妹子圖
小白學 Python 爬蟲(17):Requests 基礎使用
小白學 Python 爬蟲(18):Requests 進階操做
小白學 Python 爬蟲(21):解析庫 Beautiful Soup(上)
小白學 Python 爬蟲(22):解析庫 Beautiful Soup(下)
小白學 Python 爬蟲(23):解析庫 pyquery 入門
小白學 Python 爬蟲(26):爲啥買不起上海二手房你都買不起
小白學 Python 爬蟲(27):自動化測試框架 Selenium 從入門到放棄(上)
小白學 Python 爬蟲(28):自動化測試框架 Selenium 從入門到放棄(下)
小白學 Python 爬蟲(29):Selenium 獲取某大型電商網站商品信息
小白學 Python 爬蟲(31):本身構建一個簡單的代理池
小白學 Python 爬蟲(32):異步請求庫 AIOHTTP 基礎入門
小白學 Python 爬蟲(33):爬蟲框架 Scrapy 入門基礎(一)
小白學 Python 爬蟲(34):爬蟲框架 Scrapy 入門基礎(二)
小白學 Python 爬蟲(35):爬蟲框架 Scrapy 入門基礎(三) Selector 選擇器
小白學 Python 爬蟲(36):爬蟲框架 Scrapy 入門基礎(四) Downloader Middleware
小白學 Python 爬蟲(37):爬蟲框架 Scrapy 入門基礎(五) Spider Middleware
小白學 Python 爬蟲(38):爬蟲框架 Scrapy 入門基礎(六) Item Pipeline
小白學 Python 爬蟲(39): JavaScript 渲染服務 Scrapy-Splash 入門
小白學 Python 爬蟲(40):爬蟲框架 Scrapy 入門基礎(七)對接 Selenium 實戰
前面咱們介紹了使用 Scrapy 對接 Selenium 來抓取由 JavaScript 動態渲染的網頁,那麼除了這種方式,是否還有其餘的解決方案?
答案固然是確定的,前面咱們一樣介紹了 Splash 這個 JavaScript 動態渲染服務,本篇文章,咱們就來介紹如何使用 Scrapy 對接 Splash 抓取由 JavaScript 動態渲染的網頁。
首先需確保已經正確安裝 Splash 服務,同時包括 Scrapy-Splash 庫,尚未安裝的同窗,能夠參考前面的文章 「小白學 Python 爬蟲(39): JavaScript 渲染服務 Scrapy-Splash 入門」 進行安裝。
本篇內容仍是新建一個新的 Scrapy 項目,而且命名爲 scrapy_splash_demo ,命令以下:
scrapy startproject scrapy_splash_demo
記得找一個本身喜歡的目錄,最好是純英文目錄。
而後新建一個 Spider ,命令以下:
scrapy genspider jd www.jd.com
本篇的示例嘛仍是使用以前 Splash 的示例,畢竟本文的內容主要是介紹 Scrapy 如何對接 Splash ,固然另外一個更主要的緣由是小編也比較懶嘛~~~
這裏的配置能夠參考官方的 Github 倉庫,連接:https://github.com/scrapy-plugins/scrapy-splash 。
首先先在 settings.py
中添加 Splash 服務的地址,由於小編這裏使用的是本地的服務,因此直接就配置了本地的連接。
SPLASH_URL = 'http://localhost:8050/'
若是 Splash 服務是在遠端的服務器上運行的,那麼這裏就應該配置遠端服務器的地址,如 Splash 服務是運行在遠端的 172.16.15.177 上的,那麼須要的配置就是:
SPLASH_URL = 'http://172.16.15.177:8050/'
接下里須要配置幾個 DOWNLOADER_MIDDLEWARES
,以下:
DOWNLOADER_MIDDLEWARES = { 'scrapy_splash.SplashCookiesMiddleware': 723, 'scrapy_splash.SplashMiddleware': 725, 'scrapy.downloadermiddlewares.httpcompression.HttpCompressionMiddleware': 810, }
咱們還須要配置一個 SPIDER_MIDDLEWARES
,以下:
SPIDER_MIDDLEWARES = { 'scrapy_splash.SplashDeduplicateArgsMiddleware': 100, }
接下來,須要配置一個去重的 Python 類 SplashAwareDupeFilter
,以下:
DUPEFILTER_CLASS = 'scrapy_splash.SplashAwareDupeFilter'
咱們還須要配置一個 Cache 存儲的 SplashAwareFSCacheStorage
,以下:
HTTPCACHE_STORAGE = 'scrapy_splash.SplashAwareFSCacheStorage'
接下來,咱們就能夠開始搞事情了。
上面咱們已經將該配置的都配置完成了,這裏咱們能夠直接使用 SplashRequest 對象並傳遞相應的參數, Scrapy 會將此請求轉發給 Splash ,Splash 將頁面加載渲染,渲染完成後再將結果傳遞回來,這時的 Response 就是通過 Splash 渲染的結果了,這裏直接交給 Spider 解析就行了。
咱們先來看下官方的示例,以下:
yield SplashRequest(url, self.parse_result, args={ # optional; parameters passed to Splash HTTP API 'wait': 0.5, # 'url' is prefilled from request url # 'http_method' is set to 'POST' for POST requests # 'body' is set to request body for POST requests }, endpoint='render.json', # optional; default is render.html splash_url='<url>', # optional; overrides SPLASH_URL slot_policy=scrapy_splash.SlotPolicy.PER_DOMAIN, # optional )
這裏直接構造了一個 SplashRequest 對象,前兩個參數是目標 URL 以及回調的方法,另外咱們能夠經過 args 傳遞一些參數,如等待的時間,這個示例中是 0.5 。
更多的說明仍是參考官方 Github 倉庫,地址:https://github.com/scrapy-plugins/scrapy-splash 。
或者咱們也能夠使用 scrapy.Request , Splash 相關的配置經過 meta 配置就行了,接着看一個官方的示例,以下:
yield scrapy.Request(url, self.parse_result, meta={ 'splash': { 'args': { # set rendering arguments here 'html': 1, 'png': 1, # 'url' is prefilled from request url # 'http_method' is set to 'POST' for POST requests # 'body' is set to request body for POST requests }, # optional parameters 'endpoint': 'render.json', # optional; default is render.json 'splash_url': '<url>', # optional; overrides SPLASH_URL 'slot_policy': scrapy_splash.SlotPolicy.PER_DOMAIN, 'splash_headers': {}, # optional; a dict with headers sent to Splash 'dont_process_response': True, # optional, default is False 'dont_send_headers': True, # optional, default is False 'magic_response': False, # optional, default is True } })
這兩種發送 Request 請求的方式是相同的,選哪一個均可以。
本篇文章中使用的 Lua 腳本仍是以前文章中的腳本,具體 Lua 腳本內容以下:
function main(splash, args) splash:go("https://www.jd.com/") return { url = splash:url(), jpeg = splash:jpeg(), har = splash:har(), cookies = splash:get_cookies() } end
結果以下:
接下來,咱們在 Spider 中使用 SplashRequest 對接 Lua 腳本就行了,事情就是這麼簡單,以下:
# -*- coding: utf-8 -*- import scrapy from scrapy_splash import SplashRequest lua_script = """ function main(splash, args) splash:go(args.url) return { url = splash:url(), jpeg = splash:jpeg(), har = splash:har(), cookies = splash:get_cookies() } end """ class JdSpider(scrapy.Spider): name = 'jd' allowed_domains = ['www.jd.com'] start_urls = ['http://www.jd.com/'] def start_requests(self): url = 'https://www.jd.com/' yield SplashRequest(url=url, callback=self.parse) def parse(self, response): self.logger.debug(response.text)
Spider 寫好了之後能夠使用命令運行這個爬蟲了,命令以下:
scrapy crawl jd
具體的結果小編這裏就不貼了,只是簡單的將響應回來的數據已日誌的形式打印出來了,不過若是仔細觀察打出來的數據,能夠看到原來由 JavaScript 動態渲染的部分也打印出來了,說明咱們的 Scrapy 對接 Splash 實戰成功。
本系列的全部代碼小編都會放在代碼管理倉庫 Github 和 Gitee 上,方便你們取用。
原文出處:https://www.cnblogs.com/babycomeon/p/12199536.html