成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

Python3網(wǎng)絡(luò)爬蟲實戰(zhàn)---38、動態(tài)渲染頁面抓取:Splash的使用

姘擱『 / 3587人閱讀

摘要:上一篇文章網(wǎng)絡(luò)爬蟲實戰(zhàn)動態(tài)渲染頁面抓取下一篇文章是一個渲染服務(wù),是一個帶有的輕量級瀏覽器,同時它對接了中的和庫,利用它我們同樣可以實現(xiàn)動態(tài)渲染頁面的抓取。

上一篇文章:Python3網(wǎng)絡(luò)爬蟲實戰(zhàn)---37、動態(tài)渲染頁面抓取:Selenium
下一篇文章:

Splash 是一個 JavaScript 渲染服務(wù),是一個帶有 HTTP API 的輕量級瀏覽器,同時它對接了 Python 中的 Twisted和 QT 庫,利用它我們同樣可以實現(xiàn)動態(tài)渲染頁面的抓取。

1. 功能介紹

利用 Splash 我們可以實現(xiàn)如下功能:

異步方式處理多個網(wǎng)頁渲染過程

獲取渲染后的頁面的源代碼或截圖

通過關(guān)閉圖片渲染或者使用 Adblock 規(guī)則來加快頁面渲染速度

可執(zhí)行特定的 JavaScript 腳本

可通過 Lua 腳本來控制頁面渲染過程獲取渲染的詳細(xì)過程并通過 HAR(HTTP Archive)格式呈現(xiàn)

接下來我們來了解一下它的具體用法。

2. 準(zhǔn)備工作

在本節(jié)開始之前請確保已經(jīng)正確安裝好了 Splash 并可以正常運行服務(wù),如沒有安裝可以參考第一章的安裝說明。

3. 實例引入

首先我們可以通過 Splash 提供的 Web 頁面來測試 Splash的渲染過程,例如我們在本機(jī) 8050 端口運行了 Splash 服務(wù),打開:http://localhost:8050/ 即可看到其 Web 頁面,如圖 7-6 所示:

圖 7-6 Web 頁面
在右側(cè)呈現(xiàn)的是一個渲染示例,我們可以看到在上方有一個輸入框,默認(rèn)是:http://google.com,我們在這里換成百度測試一下,將內(nèi)容更改為:https://www.baidu.com,然后點擊按鈕,開始渲染,結(jié)果如圖 7-7 所示:

圖 7-7 運行結(jié)果
可以看到網(wǎng)頁的返回結(jié)果呈現(xiàn)了渲染截圖、HAR 加載統(tǒng)計數(shù)據(jù)、網(wǎng)頁的源代碼。
通過 HAR 的結(jié)果我們可以看到 Splash 執(zhí)行了整個網(wǎng)頁的渲染過程,包括 CSS、JavaScript 的加載等過程,呈現(xiàn)的頁面和我們在瀏覽器得到的結(jié)果完全一致。
那么這個過程是由什么來控制的呢?我們重新返回首頁可以看到實際上是有一段腳本,內(nèi)容如下:

function main(splash, args)
? assert(splash:go(args.url))
? assert(splash:wait(0.5))
? return {
??? html = splash:html(),
??? png = splash:png(),
??? har = splash:har(),
? }
end

這個腳本是實際是 Lua 語言寫的腳本,Lua也是一門編程語言,簡潔易用。
即使我們不懂這個語言的語法,但通過腳本表面意思我們也可以大致了解到它是首先調(diào)用 go() 方法去加載頁面,然后調(diào)用 wait() 方法等待了一定的時間,最后返回了頁面的源碼、截圖和 HAR 信息。
所以到這里我們可以大體了解到 Splash 是通過 Lua 腳本來控制了頁面的加載過程,加載過程完全模擬瀏覽器,最后可返回各種格式的結(jié)果,如網(wǎng)頁源碼、截圖等。
所以接下來我們要學(xué)會用 Splash 的話,一是需要了解其中 Lua 腳本的寫法,二是需要了解相關(guān) API 的用法,那么接下來我們就來了解一下這兩部分內(nèi)容。

4. Splash Lua腳本

Splash可以通過Lua腳本執(zhí)行一系列渲染操作,這樣我們就可以用Splash來模擬類似Chrome、PhantomJS的操作了。
首先我們先對 Splash Lua 腳本的用法有一個基本的認(rèn)識,先了解一下它的入口和執(zhí)行方式。

入口及返回值

首先我們來看一個基本實例:

function main(splash, args)
  splash:go("http://www.baidu.com")
  splash:wait(0.5)
  local title = splash:evaljs("document.title")
  return {title=title}
end

我們將代碼粘貼到剛才我們所打開的:http://localhost:8050/ 的代碼編輯區(qū)域,然后點擊按鈕來測試一下。
這樣我們就會看到其返回了網(wǎng)頁的標(biāo)題,這里我們是通過 evaljs() 方法傳入 JavaScript 腳本,而 document.title 的執(zhí)行結(jié)果就是返回網(wǎng)頁標(biāo)題,執(zhí)行完畢后賦值給一個 title 變量,隨后將其返回,這樣就可以看到其返回結(jié)果就是網(wǎng)頁標(biāo)題了,如圖 7-8 所示:

圖 7-8 運行結(jié)果
注意到我們在這里定義的方法名稱叫做 main(),這個名稱必須是固定的,Splash 會默認(rèn)調(diào)用這個方法。
方法的返回值可以是字典形式、也可以是字符串形式,最后都會轉(zhuǎn)化為一個 Splash HTTP Response,例如:

function main(splash)
??? return {hello="world!"}
end

這樣即返回了一個字典形式的內(nèi)容。

function main(splash)
??? return "hello"
end

這樣即返回了一個字符串形式的內(nèi)容,同樣是可以的。

異步處理

Splash是支持異步處理的,但是這里我們并沒有顯式地指明回調(diào)方法,其回調(diào)的跳轉(zhuǎn)是在Splash內(nèi)部完成的,我們先來看一個例子:

function main(splash, args)
? local example_urls = {"www.baidu.com", "www.taobao.com", "www.zhihu.com"}
? local urls = args.urls or example_urls
? local results = {}
? for index, url in ipairs(urls) do
??? local ok, reason = splash:go("http://" .. url)
??? if ok then
????? splash:wait(2)
????? results[url] = splash:png()
??? end
? end
? return results
end

運行后的返回結(jié)果是三個站點的截圖,如圖 7-9 所示:

圖 7-9 運行結(jié)果
在腳本內(nèi)調(diào)用了 wait() 方法,這類似于 Python 中的 sleep(),參數(shù)為等待的秒數(shù),當(dāng) Splash 執(zhí)行到此方法時,它會轉(zhuǎn)而去處理其他的任務(wù),然后在指定的時間過后再回來繼續(xù)處理。
在這里值得注意的是 Lua 腳本中的字符串拼接,和 Python不同,這里的字符串拼接使用的是 .. 操作符,而不是 +,如有必要可以簡單了解一下Lua腳本的語法,鏈接:http://www.runoob.com/lua/lua...。
另外這里我們做了加載時的異常檢測,go() 方法會返回加載頁面的結(jié)果狀態(tài),如果頁面出現(xiàn) 4XX 或 5XX 狀態(tài)碼,ok 變量就會為空,就不會返回加載后的圖片。

5. Splash對象屬性

我們注意到在前面的例子中 main() 方法的第一個參數(shù)是 splash,這個對象非常重要,類似于在 Selenium 中的WebDriver 對象:

from selenium import webdriver
browser = webdriver.Chrome()

如上所示,現(xiàn)在的 splash 對象就如同此處 Selenium 中的 browser 對象,我們可以調(diào)用它的一些屬性和方法來控制加載過程,接下來我們首先看下它的屬性。

args

splash 對象的 args 屬性可以獲取加載時配置的參數(shù),它可以獲取加載的 URL,如果為 GET 請求它還可以獲取 GET 請求參數(shù),如果為 POST 請求它可以獲取表單提交的數(shù)據(jù)。Splash 支持第二個參數(shù)直接作為 args,例如:

function main(splash, args)
??? local url = args.url
end

在這里第二個參數(shù) args 就相當(dāng)于 splash.args 屬性,以上代碼等價于:

function main(splash)
??? local url = splash.args.url
end
js_enabled

這個屬性是 Splash 的 JavaScript 執(zhí)行開關(guān),我們可以將其配置為 True 或 False 來控制是否可以執(zhí)行 JavaScript 代碼,默認(rèn)為 True,例如我們在這里禁用一下 JavaScript 的執(zhí)行:

function main(splash, args)
? splash:go("https://www.baidu.com")
? splash.js_enabled = false
? local title = splash:evaljs("document.title")
? return {title=title}
end

禁用之后,我們重新調(diào)用了 evaljs() 方法執(zhí)行 JavaScript 代碼,那么運行結(jié)果就會拋出異常:

{
??? "error": 400,
??? "type": "ScriptError",
??? "info": {
??????? "type": "JS_ERROR",
??????? "js_error_message": null,
??????? "source": "[string "function main(splash, args)
..."]",
??????? "message": "[string "function main(splash, args)
..."]:4: unknown JS error: None",
??????? "line_number": 4,
??????? "error": "unknown JS error: None",
??????? "splash_method": "evaljs"
??? },
??? "description": "Error happened while executing Lua script"
}

不過一般來說我們不用設(shè)置此屬性開關(guān),默認(rèn)開啟即可。

resource_timeout

此屬性可以設(shè)置加載的超時時間,單位是秒,如果設(shè)置為 0或 nil(類似 Python 中的 None)就代表不檢測超時,我們用一個實例感受一下:

function main(splash)
??? splash.resource_timeout = 0.1
??? assert(splash:go("https://www.taobao.com"))
??? return splash:png()
end

例如這里我們將超時時間設(shè)置為 0.1 秒,如果在 0.1 秒之內(nèi)沒有得到響應(yīng)就會拋出異常,錯誤如下:

{
??? "error": 400,
??? "type": "ScriptError",
??? "info": {
??????? "error": "network5",
??????? "type": "LUA_ERROR",
??????? "line_number": 3,
??????? "source": "[string "function main(splash)
..."]",
??????? "message": "Lua error: [string "function main(splash)
..."]:3: network5"
??? },
??? "description": "Error happened while executing Lua script"
}

此屬性適合在網(wǎng)頁加載速度較慢的情況下設(shè)置,如果超過了某個時間無響應(yīng)則直接拋出異常并忽略即可。

images_enabled

此屬性可以設(shè)置圖片是否加載,默認(rèn)情況下是加載的,但是禁用之后可以節(jié)省網(wǎng)絡(luò)流量并提高網(wǎng)頁加載速度,但是值得注意的是禁用圖片加載之后可能會影響 JavaScript 渲染,因為禁用圖片之后它的外層 DOM 節(jié)點的高度會受影響,進(jìn)而影響 DOM 節(jié)點的位置,所以如果 JavaScript 如果使用了相關(guān)變量的話,其執(zhí)行就會受到影響,不過一般情況下不會。
另外值得注意的是 Splash 使用了緩存,所以如果你一開始加載出來了網(wǎng)頁圖片,然后禁用了圖片加載,然后再重新加載頁面,之前加載好的圖片可能還會顯示出來,這時可以重啟一下 Splash 即可解決。
禁用圖片加載的示例如下:

function main(splash, args)
? splash.images_enabled = false
? assert(splash:go("https://www.jd.com"))
? return {png=splash:png()}
end

這樣返回的頁面截圖就不會帶有任何圖片,加載速度也會快很多。

plugins_enabled

此屬性可以控制瀏覽器插件是否開啟,如 Flash 插件。默認(rèn)此屬性是 False 不開啟,可以使用如下代碼控制其開啟和關(guān)閉:

splash.plugins_enabled = true/false
scroll_position

此屬性可以控制頁面的滾動偏移,通過設(shè)置此屬性我們可以控制頁面上下或左右滾動,還是比較常用的一個屬性,我們用一個實例感受一下:

function main(splash, args)
? assert(splash:go("https://www.taobao.com"))
? splash.scroll_position = {y=400}
? return {png=splash:png()}
end

這樣我們就可以控制頁面向下滾動 400 像素值,結(jié)果如圖 7-10 所示:

圖 7-10 運行結(jié)果
如果要控制左右滾動可以傳入 x 參數(shù),代碼如下:

splash.scroll_position = {x=100, y=200}
6. Splash對象方法 go()

go() 方法就是用來請求某個鏈接的方法,而且它可以模擬 GET 和 POST 請求,同時支持傳入 Headers、Form Data 等數(shù)據(jù),用法如下:

ok, reason = splash:go{url, baseurl=nil, headers=nil, http_method="GET", body=nil, formdata=nil}

參數(shù)說明如下:

url,即請求的URL。

baseurl,可選參數(shù),默認(rèn)為空,資源加載相對路徑。

headers,可選參數(shù),默認(rèn)為空,請求的 Headers。

http_method,可選參數(shù),默認(rèn)為 GET,同時支持 POST。

body,可選參數(shù),默認(rèn)為空,POST 的時候的表單數(shù)據(jù),使用的 Content-type 為 application/json。

formdata,可選參數(shù),默認(rèn)為空,POST 的時候表單數(shù)據(jù),使用的 Content-type為application/x-www-form-urlencoded。

返回的結(jié)果是結(jié)果 ok 和原因 reason 的組合,如果 ok 為空,代表網(wǎng)頁加載出現(xiàn)了錯誤,此時 reason 變量中包含了錯誤的原因,否則證明頁面加載成功,示例如下:

function main(splash, args)
? local ok, reason = splash:go{"http://httpbin.org/post", http_method="POST", body="name=Germey"}
? if ok then
??????? return splash:html()
? end
end

在這里我們模擬了一個 POST 請求,并傳入了 POST 的表單數(shù)據(jù),如果成功,則返回頁面源代碼。
運行結(jié)果如下:

{
  "args": {}, 
  "data": "", 
  "files": {}, 
  "form": {
    "name": "Germey"
  }, 
  "headers": {
    "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", 
    "Accept-Encoding": "gzip, deflate", 
    "Accept-Language": "en,*", 
    "Connection": "close", 
    "Content-Length": "11", 
    "Content-Type": "application/x-www-form-urlencoded", 
    "Host": "httpbin.org", 
    "Origin": "null", 
    "User-Agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/602.1 (KHTML, like Gecko) splash Version/9.0 Safari/602.1"
  }, 
  "json": null, 
  "origin": "60.207.237.85", 
  "url": "http://httpbin.org/post"
}

通過結(jié)果可以看到我們成功實現(xiàn)了 POST 請求并發(fā)送了表單數(shù)據(jù)。

wait()

此方法可以控制頁面等待時間,使用方法如下:

ok, reason = splash:wait{time, cancel_on_redirect=false, cancel_on_error=true}

參數(shù)說明如下:

time,等待的秒數(shù)。

cancel_on_redirect,可選參數(shù),默認(rèn) False,如果發(fā)生了重定向就停止等待,并返回重定向結(jié)果。

cancel_on_error,可選參數(shù),默認(rèn) False,如果發(fā)生了加載錯誤就停止等待。

返回結(jié)果同樣是結(jié)果 ok 和原因 reason 的組合。
我們用一個實例感受一下:

function main(splash)
??? splash:go("https://www.taobao.com")
??? splash:wait(2)
??? return {html=splash:html()}
end

如上代碼可以實現(xiàn)訪問淘寶并等待 2 秒,隨后返回頁面源代碼的功能。

jsfunc()

此方法可以直接調(diào)用 JavaScript 定義的方法,需要用雙中括號包圍,相當(dāng)于實現(xiàn)了 JavaScript 方法到 Lua 腳本的轉(zhuǎn)換,示例如下:

function main(splash, args)
? local get_div_count = splash:jsfunc([[
? function () {
??? var body = document.body;
??? var divs = body.getElementsByTagName("div");
??? return divs.length;
? }
? ]])
? splash:go("https://www.baidu.com")
? return ("There are %s DIVs"):format(
??? get_div_count())
end

運行結(jié)果:

There are 21 DIVs

首選我們聲明了一個方法,然后在頁面加載成功后調(diào)用了此方法計算出了頁面中的 div 節(jié)點的個數(shù)。
但這只是 Splash 提供的 Web 頁面功能,更多的功能我們可以使用它提供的 HTTP API 來完成 JavaScript 渲染過程。
關(guān)于更多 JavaScript 到 Lua 腳本的轉(zhuǎn)換細(xì)節(jié)可以參考官方文檔介紹:https://splash.readthedocs.io...。

evaljs()

此方法可以執(zhí)行 JavaScript 代碼并返回最后一條語句的返回結(jié)果,使用方法如下:

result = splash:evaljs(js)

比如我們可以用下面的代碼來獲取頁面的標(biāo)題:

local title = splash:evaljs("document.title")
runjs()

此方法可以執(zhí)行 JavaScript 代碼,和 evaljs() 功能類似,但是此方法更偏向于執(zhí)行某些動作或聲明某些方法,evaljs() 偏向于獲取某些執(zhí)行結(jié)果,例如:

function main(splash, args)
? splash:go("https://www.baidu.com")
? splash:runjs("foo = function() { return "bar" }")
? local result = splash:evaljs("foo()")
? return result
end

在這里我們用 runjs() 先聲明了一個 JavaScript 定義的方法,然后通過 evaljs() 來調(diào)用得到結(jié)果。
運行結(jié)果如下:

bar
autoload()

此方法可以設(shè)置在每個頁面訪問時自動加載的對象,使用方法如下:

ok, reason = splash:autoload{source_or_url, source=nil, url=nil}

參數(shù)說明如下:

source_or_url,JavaScript 代碼或者 JavaScript 庫鏈接。

source,JavaScript 代碼。

url,JavaScript 庫鏈接

但是此方法只負(fù)責(zé)加載 JavaScript 代碼或庫,不執(zhí)行任何操作,如果要執(zhí)行操作可以調(diào)用 evaljs() 或 runjs() 方法,示例如下

function main(splash, args)
? splash:autoload([[
??? function get_document_title(){
????? return document.title;
??? }
? ]])
? splash:go("https://www.baidu.com")
? return splash:evaljs("get_document_title()")
end

在這里我們調(diào)用 autoload() 聲明了一個 JavaScript 方法,然后通過 evaljs() 調(diào)用了此方法執(zhí)行。
運行結(jié)果:

百度一下,你就知道

另外我們也可以加載某些方法庫,如 jQuery,示例如下:

function main(splash, args)
? assert(splash:autoload("https://code.jquery.com/jquery-2.1.3.min.js"))
? assert(splash:go("https://www.taobao.com"))
? local version = splash:evaljs("$.fn.jquery")
? return "JQuery version: " .. version
end

運行結(jié)果:

JQuery version: 2.1.3
call_later()

此方法可以通過設(shè)置定時任務(wù)和延遲時間實現(xiàn)任務(wù)延時執(zhí)行,并且可以在執(zhí)行前通過 cancel() 方法重新執(zhí)行定時任務(wù),示例如下:

function main(splash, args)
? local snapshots = {}
? local timer = splash:call_later(function()
??? snapshots["a"] = splash:png()
??? splash:wait(1.0)
??? snapshots["b"] = splash:png()
? end, 0.2)
? splash:go("https://www.taobao.com")
? splash:wait(3.0)
? return snapshots
end

在這里我們設(shè)置了一個定時任務(wù),0.2 秒的時候獲取網(wǎng)頁截圖,然后等待 1 秒,1.2 秒時再次獲取網(wǎng)頁截圖,訪問的頁面是淘寶,最后將截圖結(jié)果返回。
運行結(jié)果如圖 7-11 所示:

圖 7-11 運行結(jié)果
我們可以發(fā)現(xiàn)第一次截圖網(wǎng)頁還沒有加載出來,截圖為空,第二次網(wǎng)頁便加載成功了。

http_get()

此方法可以模擬發(fā)送 HTTP 的 GET 請求,使用方法如下:

response = splash:http_get{url, headers=nil, follow_redirects=true}

參數(shù)說明如下:

url,請求URL。

headers,可選參數(shù),默認(rèn)為空,請求的 Headers。

follow_redirects,可選參數(shù),默認(rèn)為 True,是否啟動自動重定向。我們用一個實例來感受一下:

function main(splash, args)
? local treat = require("treat")
? local response = splash:http_get("http://httpbin.org/get")
??? return {
??? html=treat.as_string(response.body),
??? url=response.url,
??? status=response.status
??? }
end

運行結(jié)果:

Splash Response: Object
html: String (length 355)
{
? "args": {}, 
? "headers": {
??? "Accept-Encoding": "gzip, deflate", 
??? "Accept-Language": "en,*", 
??? "Connection": "close", 
??? "Host": "httpbin.org", 
??? "User-Agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/602.1 (KHTML, like Gecko) splash Version/9.0 Safari/602.1"
? }, 
? "origin": "60.207.237.85", 
? "url": "http://httpbin.org/get"
}
status: 200
url: "http://httpbin.org/get"
http_post()

和 http_get() 方法類似,此方法是模擬發(fā)送一個 POST 請求,不過多了一個參數(shù) body,使用方法如下:

response = splash:http_post{url, headers=nil, follow_redirects=true, body=nil}

參數(shù)說明如下:

url,請求URL。

headers,可選參數(shù),默認(rèn)為空,請求的 Headers。

follow_redirects,可選參數(shù),默認(rèn)為 True,是否啟動自動重定向。body,可選參數(shù),默認(rèn)為空,即表單數(shù)據(jù)。我們用一個實例感受一下:

function main(splash, args)
? local treat = require("treat")
? local json = require("json")
? local response = splash:http_post{"http://httpbin.org/post",???? 
????? body=json.encode({name="Germey"}),
????? headers={["content-type"]="application/json"}
??? }
??? return {
??? html=treat.as_string(response.body),
??? url=response.url,
??? status=response.status
??? }
end

運行結(jié)果:

Splash Response: Object
html: String (length 533)
{
? "args": {}, 
? "data": "{"name": "Germey"}", 
? "files": {}, 
? "form": {}, 
? "headers": {
??? "Accept-Encoding": "gzip, deflate", 
??? "Accept-Language": "en,*", 
??? "Connection": "close", 
??? "Content-Length": "18", 
??? "Content-Type": "application/json", 
??? "Host": "httpbin.org", 
??? "User-Agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/602.1 (KHTML, like Gecko) splash Version/9.0 Safari/602.1"
? }, 
? "json": {
??? "name": "Germey"
? }, 
? "origin": "60.207.237.85", 
? "url": "http://httpbin.org/post"
}
status: 200
url: "http://httpbin.org/post"

可以看到在這里我們成功模擬提交了 POST 請求并發(fā)送了表單數(shù)據(jù)。

set_content()

此方法可以用來設(shè)置頁面的內(nèi)容,示例如下:

function main(splash)
??? assert(splash:set_content("

hello

")) ??? return splash:png() end

運行結(jié)果如圖 7-12 所示:

圖 7-12 運行結(jié)果

html()

此方法可以用來獲取網(wǎng)頁的源代碼,非常簡單又常用的方法,示例如下:

function main(splash, args)
? splash:go("https://httpbin.org/get")
? return splash:html()
end

運行結(jié)果:

{
  "args": {}, 
  "headers": {
    "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", 
    "Accept-Encoding": "gzip, deflate", 
    "Accept-Language": "en,*", 
    "Connection": "close", 
    "Host": "httpbin.org", 
    "User-Agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/602.1 (KHTML, like Gecko) splash Version/9.0 Safari/602.1"
  }, 
  "origin": "60.207.237.85", 
  "url": "https://httpbin.org/get"
}
png()

此方法可以用來獲取 PNG 格式的網(wǎng)頁截圖,示例如下:

function main(splash, args)
? splash:go("https://www.taobao.com")
? return splash:png()
end
jpeg()

此方法可以用來獲取 JPEG 格式的網(wǎng)頁截圖,示例如下:

function main(splash, args)
? splash:go("https://www.taobao.com")
? return splash:jpeg()
end
har()

此方法可以用來獲取頁面加載過程描述,示例如下:

function main(splash, args)
? splash:go("https://www.baidu.com")
? return splash:har()
end

運行結(jié)果如圖 7-13 所示:

圖 7-13 運行結(jié)果
在這里顯示了頁面加載過程中的每個請求記錄詳情。

url()

此方法可以獲取當(dāng)前正在訪問的 URL,示例如下:

function main(splash, args)
? splash:go("https://www.baidu.com")
? return splash:url()
end

運行結(jié)果如下:

https://www.baidu.com/
get_cookies()

此方法可以獲取當(dāng)前頁面的 Cookies,示例如下:

function main(splash, args)
? splash:go("https://www.baidu.com")
? return splash:get_cookies()
end

運行結(jié)果如下:

Splash Response: Array[2]
0: Object
domain: ".baidu.com"
expires: "2085-08-21T20:13:23Z"
httpOnly: false
name: "BAIDUID"
path: "/"
secure: false
value: "C1263A470B02DEF45593B062451C9722:FG=1"
1: Object
domain: ".baidu.com"
expires: "2085-08-21T20:13:23Z"
httpOnly: false
name: "BIDUPSID"
path: "/"
secure: false
value: "C1263A470B02DEF45593B062451C9722"
add_cookie()

此方法可以為當(dāng)前頁面添加 Cookie,用法如下:

cookies = splash:add_cookie{name, value, path=nil, domain=nil, expires=nil, httpOnly=nil, secure=nil}

方法的各個參數(shù)代表了 Cookie 的各個屬性。
示例如下:

function main(splash)
??? splash:add_cookie{"sessionid", "237465ghgfsd", "/", domain="http://example.com"}
??? splash:go("http://example.com/")
??? return splash:html()
end
clear_cookies()

此方法可以清除所有的 Cookies,示例如下:

function main(splash)
??? splash:go("https://www.baidu.com/")
??? splash:clear_cookies()
??? return splash:get_cookies()
end

在這里我們清除了所有的 Cookies,然后再調(diào)用 get_cookies() 并將結(jié)果返回。
運行結(jié)果:

Splash Response: Array[0]

可以看到Cookies被全部清空,沒有任何結(jié)果。

get_viewport_size()

此方法可以獲取當(dāng)前瀏覽器頁面的大小,即寬高,示例如下:

function main(splash)
??? splash:go("https://www.baidu.com/")
??? return splash:get_viewport_size()
end

運行結(jié)果:

Splash Response: Array[2]
0: 1024
1: 768
set_viewport_size()

此方法可以設(shè)置當(dāng)前瀏覽器頁面的大小,即寬高,用法如下:

splash:set_viewport_size(width, height)

例如這里我們訪問一個寬度自適應(yīng)的頁面,示例如下:

function main(splash)
??? splash:set_viewport_size(400, 700)
??? assert(splash:go("http://cuiqingcai.com"))
??? return splash:png()
end

運行結(jié)果如圖 7-14 所示:

圖 7-14 運行結(jié)果

set_viewport_full()

此方法可以設(shè)置瀏覽器全屏顯示,示例如下:

function main(splash)
??? splash:set_viewport_full()
??? assert(splash:go("http://cuiqingcai.com"))
??? return splash:png()
end
set_user_agent()

此方法可以設(shè)置瀏覽器的 User-Agent,示例如下:

function main(splash)
? splash:set_user_agent("Splash")
? splash:go("http://httpbin.org/get")
? return splash:html()
end

在這里我們將瀏覽器的 User-Agent 設(shè)置為 Splash,運行結(jié)果如下:

{
  "args": {}, 
  "headers": {
    "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", 
    "Accept-Encoding": "gzip, deflate", 
    "Accept-Language": "en,*", 
    "Connection": "close", 
    "Host": "httpbin.org", 
    "User-Agent": "Splash"
  }, 
  "origin": "60.207.237.85", 
  "url": "http://httpbin.org/get"
}

可以看到此處 User-Agent 被成功設(shè)置。

set_custom_headers()

此方法可以設(shè)置請求的 Headers,示例如下:

function main(splash)
? splash:set_custom_headers({
???? ["User-Agent"] = "Splash",
???? ["Site"] = "Splash",
? })
? splash:go("http://httpbin.org/get")
? return splash:html()
end

在這里我們設(shè)置了 Headers 中的 User-Agent 和 Site 屬性,運行結(jié)果:

{
  "args": {}, 
  "headers": {
    "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", 
    "Accept-Encoding": "gzip, deflate", 
    "Accept-Language": "en,*", 
    "Connection": "close", 
    "Host": "httpbin.org", 
    "Site": "Splash", 
    "User-Agent": "Splash"
  }, 
  "origin": "60.207.237.85", 
  "url": "http://httpbin.org/get"
}

可以看到結(jié)果的 Headers 中兩個字段被成功設(shè)置。

select()

select() 方法可以選中符合條件的第一個節(jié)點,如果有多個節(jié)點符合條件,則只會返回一個,其參數(shù)是 CSS 選擇器,示例如下:

function main(splash)
? splash:go("https://www.baidu.com/")
? input = splash:select("#kw")
? input:send_text("Splash")
? splash:wait(3)
? return splash:png()
end

在這里我們首先訪問了百度,然后選中了搜索框,隨后調(diào)用了 send_text() 方法填寫了文本,然后返回網(wǎng)頁截圖。
結(jié)果如圖 7-15 所示:

圖 7-15 運行結(jié)果
可以看到我們成功填寫了輸入框。

select_all()

此方法可以選中所有的符合條件的節(jié)點,其參數(shù)是 CSS 選擇器。示例如下

function main(splash)
? local treat = require("treat")
? assert(splash:go("http://quotes.toscrape.com/"))
? assert(splash:wait(0.5))
? local texts = splash:select_all(".quote .text")
? local results = {}
? for index, text in ipairs(texts) do
??? results[index] = text.node.innerHTML
? end
? return treat.as_array(results)
end

在這里我們通過 CSS 選擇器選中了節(jié)點的正文內(nèi)容,隨后遍歷了所有節(jié)點,然后將其中的文本獲取了下來。
運行結(jié)果:

Splash Response: Array[10]
0: "“The world as we have created it is a process of our thinking. It cannot be changed without changing our thinking.”"
1: "“It is our choices, Harry, that show what we truly are, far more than our abilities.”"
2: “There are only two ways to live your life. One is as though nothing is a miracle. The other is as though everything is a miracle.”
3: "“The person, be it gentleman or lady, who has not pleasure in a good novel, must be intolerably stupid.”"
4: "“Imperfection is beauty, madness is genius and it"s better to be absolutely ridiculous than absolutely boring.”"
5: "“Try not to become a man of success. Rather become a man of value.”"
6: "“It is better to be hated for what you are than to be loved for what you are not.”"
7: "“I have not failed. I"ve just found 10,000 ways that won"t work.”"
8: "“A woman is like a tea bag; you never know how strong it is until it"s in hot water.”"
9: "“A day without sunshine is like, you know, night.”"

可以發(fā)現(xiàn)我們成功將 10 個節(jié)點的正文內(nèi)容獲取了下來。

mouse_click()

此方法可以模擬鼠標(biāo)點擊操作,傳入的參數(shù)為坐標(biāo)值 x、y,也可以直接選中某個節(jié)點直接調(diào)用此方法,示例如下:

function main(splash)
? splash:go("https://www.baidu.com/")
? input = splash:select("#kw")
? input:send_text("Splash")
? submit = splash:select("#su")
? submit:mouse_click()
? splash:wait(3)
? return splash:png()
end

在這里我們首先選中了頁面的輸入框,輸入了文本,然后選中了提交按鈕,調(diào)用了 mouse_click() 方法提交查詢,然后頁面等待三秒,返回截圖,結(jié)果如圖 7-16 所示:

圖 7-16 運行結(jié)果
可以看到在這里我們成功獲取了查詢后的頁面內(nèi)容,模擬了百度搜索操作。
以上我們介紹了 Splash 的常用 API 操作,還有一些 API 在這不再一一介紹,更加詳細(xì)和權(quán)威的說明可以參見官方文檔:https://splash.readthedocs.io...,此頁面介紹了 splash 對象的所有 API 操作,另外還有針對于頁面元素的 API 操作,鏈接為:https://splash.readthedocs.io...。

7. Splash API調(diào)用

在上文中我們說明了 Splash Lua 腳本的用法,但這些腳本是在 Splash 頁面里面測試運行的,我們?nèi)绾尾拍芾肧plash 來渲染頁面呢?怎樣才能和 Python 程序結(jié)合使用并抓取 JavaScript 渲染的頁面呢?
其實 Splash 給我們提供了一些 HTTP API 接口,我們只需要請求這些接口并傳遞相應(yīng)的參數(shù)即可獲取頁面渲染后的結(jié)果,下面我們對這些接口進(jìn)行介紹:

render.html

此接口用于獲取 JavaScript 渲染的頁面的 HTML 代碼,接口地址就是 Splash 的運行地址加此接口名稱,例如:http://localhost:8050/render.html,我們可以用 curl 來測試一下:

curl http://localhost:8050/render.html?url=https://www.baidu.com

我們給此接口傳遞了一個 url 參數(shù)指定渲染的 URL,返回結(jié)果即頁面渲染后的源代碼。
如果用 Python 實現(xiàn)的話,代碼如下:

import requests
url = "http://localhost:8050/render.html?url=https://www.baidu.com"
response = requests.get(url)
print(response.text)

這樣我們就可以成功輸出百度頁面渲染后的源代碼了。
另外此接口還可以指定其他參數(shù),如 wait 指定等待秒數(shù),如果我們要確保頁面完全加載出來可以增加等待時間,例如:

import requests
url = "http://localhost:8050/render.html?url=https://www.taobao.com&wait=5"
response = requests.get(url)
print(response.text)

如果增加了此等待時間后,得到響應(yīng)的時間就會相應(yīng)變長,如在這里我們會等待大約 5 秒多鐘即可獲取 JavaScript 渲染后的淘寶頁面源代碼。
另外此接口還支持代理設(shè)置、圖片加載設(shè)置、Headers設(shè)置、請求方法設(shè)置,具體的用法可以參見官方文檔:https://splash.readthedocs.io...。

render.png

此接口可以獲取網(wǎng)頁截圖,參數(shù)相比 render.html 又多了幾個,如 width、height 來控制寬高,返回的是 PNG 格式的圖片二進(jìn)制數(shù)據(jù)。
示例如下:

curl http://localhost:8050/render.png?url=https://www.taobao.com&wait=5&width=1000&height=700

在這里我們還傳入了 width 和 height 來放縮頁面大小為 1000x700 像素。
如果用 Python 實現(xiàn),我們可以將返回的二進(jìn)制數(shù)據(jù)保存為PNG 格式的圖片,實現(xiàn)如下:

import requests

url = "http://localhost:8050/render.png?url=https://www.jd.com&wait=5&width=1000&height=700"
response = requests.get(url)
with open("taobao.png", "wb") as f:
??? f.write(response.content)

得到的圖片如圖 7-17 所示:

圖 7-17 運行結(jié)果
這樣我們就成功獲取了京東首頁渲染完成后的頁面截圖,詳細(xì)的參數(shù)設(shè)置可以參考官網(wǎng)文檔:https://splash.readthedocs.io...。

render.jpeg

此接口和 render.png 類似,不過它返回的是 JPEG 格式的圖片二進(jìn)制數(shù)據(jù)。
另外此接口相比 render.png 還多了一個參數(shù) quality,可以用來設(shè)置圖片質(zhì)量。

render.har

此接口用于獲取頁面加載的 HAR 數(shù)據(jù),示例如下:

curl http://localhost:8050/render.har?url=https://www.jd.com&wait=5

返回結(jié)果非常多,是一個 Json 格式的數(shù)據(jù),里面包含了頁面加載過程中的 HAR 數(shù)據(jù)。
結(jié)果如圖 7-18 所示:

圖 7-18 運行結(jié)果

render.json

此接口包含了前面接口的所有功能,返回結(jié)果是 Json 格式,示例如下:

curl http://localhost:8050/render.json?url=https://httpbin.org

結(jié)果如下:

{"title": "httpbin(1): HTTP Client Testing Service", "url": "https://httpbin.org/", "requestedUrl": "https://httpbin.org/", "geometry": [0, 0, 1024, 768]}

可以看到這里以 Json 形式返回了相應(yīng)的請求數(shù)據(jù)。
我們可以通過傳入不同的參數(shù)控制其返回的結(jié)果,如傳入html=1,返回結(jié)果即會增加源代碼數(shù)據(jù),傳入 png=1,返回結(jié)果機(jī)會增加頁面 PNG 截圖數(shù)據(jù),傳入har=1則會獲得頁面 HAR 數(shù)據(jù),例如:

curl http://localhost:8050/render.json?url=https://httpbin.org&html=1&har=1

這樣返回的 Json 結(jié)果便會包含網(wǎng)頁源代碼和 HAR 數(shù)據(jù)。
還有更多參數(shù)設(shè)置可以參考官方文檔:https://splash.readthedocs.io...。

execute

此接口才是最為強(qiáng)大的接口,我們在前面說了很多 Splash Lua 腳本的操作,用此接口便可以實現(xiàn)和 Lua 腳本的對接。
前面的 render.html、render.png 等接口對于一般的 JavaScript 渲染頁面是足夠了,但是如果要實現(xiàn)一些交互操作的話還是無能為力的,所以這里就需要使用此 execute 接口來對接 Lua 腳本和網(wǎng)頁進(jìn)行交互了。
我們先實現(xiàn)一個最簡單的腳本,直接返回數(shù)據(jù):

function main(splash)
??? return "hello"
end

然后將此腳本轉(zhuǎn)化為 URL 編碼后的字符串,拼接到 execute 接口后面,示例如下:

curl http://localhost:8050/execute?lua_source=function+main%28splash%29%0D%0A++return+%27hello%27%0D%0Aend

運行結(jié)果:

hello

在這里我們通過 lua_source 參數(shù)傳遞了轉(zhuǎn)碼后的 Lua 腳本,通過 execute 接口獲取了最終腳本的執(zhí)行結(jié)果。
那么在這里我們更加關(guān)心的肯定是如何用 Python 來實現(xiàn),上例用 Python 實現(xiàn)如下:

import requests
from urllib.parse import quote

lua = """
function main(splash)
??? return "hello"
end
"""

url = "http://localhost:8050/execute?lua_source=" + quote(lua)
response = requests.get(url)
print(response.text)

運行結(jié)果:

hello

在這里我們用 Python 中的三引號來將 Lua 腳本包括起來,然后用 urllib.parse 模塊里的 quote()方法將腳本進(jìn)行 URL 轉(zhuǎn)碼,隨后構(gòu)造了 Splash 請求 URL,將其作為 lua_source 參數(shù)傳遞,這樣運行結(jié)果就會顯示 Lua 腳本執(zhí)行后的結(jié)果。
我們再來一個實例看一下:

import requests
from urllib.parse import quote

lua = """
function main(splash, args)
? local treat = require("treat")
? local response = splash:http_get("http://httpbin.org/get")
??? return {
??? html=treat.as_string(response.body),
??? url=response.url,
??? status=response.status
??? }
end
"""

url = "http://localhost:8050/execute?lua_source=" + quote(lua)
response = requests.get(url)
print(response.text)

運行結(jié)果:

{"url": "http://httpbin.org/get", "status": 200, "html": "{
? "args": {}, 
? "headers": {
??? "Accept-Encoding": "gzip, deflate", 
??? "Accept-Language": "en,*", 
??? "Connection": "close", 
??? "Host": "httpbin.org", 
??? "User-Agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/602.1 (KHTML, like Gecko) splash Version/9.0 Safari/602.1"
? }, 
? "origin": "60.207.237.85", 
? "url": "http://httpbin.org/get"
}
"}

返回結(jié)果是 Json 形式,我們成功獲取了請求的 URL、狀態(tài)碼和網(wǎng)頁源代碼。
如此一來,我們之前所說的 Lua 腳本均可以用此方式與 Python 進(jìn)行對接,這樣的話,所有網(wǎng)頁的動態(tài)渲染、模擬點擊、表單提交、頁面滑動、延時等待后的一些結(jié)果均可以自由控制,獲取頁面源碼和截圖都不在話下。

8、Splash負(fù)載均衡配置

如果我們用 Splash 來做 JavaScript 動態(tài)渲染的頁面的抓取的話,如果爬取的量非常大,任務(wù)非常多,如果我們用一個 Splash 服務(wù)來處理的話未免壓力太大了,所以我們可以考慮搭建一個負(fù)載均衡器來把壓力分散到各個服務(wù)器上,這樣相當(dāng)于多臺機(jī)器多個服務(wù)共同參與任務(wù)的處理,可以減小單個 Splash 服務(wù)的壓力。

1. 配置Splash服務(wù)

要搭建 Splash 負(fù)載均衡首先我們需要有多個 Splash 服務(wù),假如在這里我在四臺遠(yuǎn)程主機(jī)的 8050 端口上都開啟了 Splash 服務(wù),它們的服務(wù)地址分別為:41.159.27.223:8050、41.159.27.221:8050、41.159.27.9:8050、41.159.117.119:8050,四個服務(wù)完全一致,都是通過 Docker 的 Splash 鏡像開啟的,訪問任何一個服務(wù)都可以使用 Splash 服務(wù)。

2. 配置負(fù)載均衡

接下來我們可以選用任意一臺帶有公網(wǎng) IP 的主機(jī)來配置負(fù)載均衡,首先需要在這臺主機(jī)上裝好 Nginx,然后修改 Nginx 的配置文件 nginx.conf,添加如下內(nèi)容:

http {
    upstream splash {
        least_conn;
        server 41.159.27.223:8050;
        server 41.159.27.221:8050;
        server 41.159.27.9:8050;
        server 41.159.117.119:8050;
    }
    server {
        listen 8050;
        location / {
            proxy_pass http://splash;
        }
    }
}

這樣我們通過 upstream 字段定義了一個名字叫做 splash 的服務(wù)集群配置,least_conn 代表最少鏈接負(fù)載均衡,它適合處理請求處理時間長短不一造成服務(wù)器過載的情況。

或者我們也可以不指定配置,配置如下:

upstream splash {
    server 41.159.27.223:8050;
    server 41.159.27.221:8050;
    server 41.159.27.9:8050;
    server 41.159.117.119:8050;
}

這樣默認(rèn)以輪詢策略實現(xiàn)負(fù)載均衡,每個服務(wù)器的壓力相同,此策略適合服務(wù)器配置相當(dāng),無狀態(tài)且短平快的服務(wù)使用。

另外我們還可以指定權(quán)重,配置如下:

upstream splash {
    server 41.159.27.223:8050 weight=4;
    server 41.159.27.221:8050 weight=2;
    server 41.159.27.9:8050 weight=2;
    server 41.159.117.119:8050 weight=1;
}

我們通過 weight 指定了各個服務(wù)的權(quán)重,權(quán)重越高分配到處理的請求越多,假如不同的服務(wù)器配置差別比較大的話,就可以使用此種配置。

最后還有一種 IP 哈希負(fù)載均衡,配置如下:

upstream splash {
    ip_hash;
    server 41.159.27.223:8050;
    server 41.159.27.221:8050;
    server 41.159.27.9:8050;
    server 41.159.117.119:8050;
}

服務(wù)器根據(jù)請求客戶端的 IP 地址進(jìn)行哈希計算,確保使用同一個服務(wù)器響應(yīng)請求,這種策略適合有狀態(tài)的服務(wù),如用戶登錄后訪問某個頁面的情形。不過對于 Splash 來說不需要。

我們可以根據(jù)不同的情形選用不同的配置,配置完成后重啟一下 Nginx 服務(wù):

sudo nginx -s reload

這樣直接訪問 Nginx 所在服務(wù)器的 8050 端口即可實現(xiàn)負(fù)載均衡了。

3. 配置認(rèn)證

現(xiàn)在 Splash 是公開訪問的,如果我們不想讓其被公開訪問還可以配置認(rèn)證,仍然借助于 Nginx 即可,可以在 server 的 location 字段中添加一個 auth_basic 和 auth_basic_user_file 字段,配置如下:

http {
    upstream splash {
        least_conn;
        server 41.159.27.223:8050;
        server 41.159.27.221:8050;
        server 41.159.27.9:8050;
        server 41.159.117.119:8050;
    }
    server {
        listen 8050;
        location / {
            proxy_pass http://splash;
            auth_basic "Restricted";
            auth_basic_user_file /etc/nginx/conf.d/.htpasswd;
        }
    }
}

在這里使用的用戶名密碼配置放置在 /etc/nginx/conf.d 目錄,我們需要使用 htpasswd 命令創(chuàng)建,例如創(chuàng)建一個用戶名為 admin 的文件,命令如下:

htpasswd -c .htpasswd admin

接下就會提示我們輸入密碼,輸入兩次之后,就會生成密碼文件,查看一下內(nèi)容:

cat .htpasswd 
admin:5ZBxQr0rCqwbc

配置完成之后我們重啟一下 Nginx 服務(wù),運行如下命令:

sudo nginx -s reload

這樣訪問認(rèn)證就成功配置好了。

4. 測試

最后我們可以用代碼來測試一下負(fù)載均衡的配置,看看到底是不是每次請求會切換IP,利用 http://httpbin.org/get 測試即可,代碼實現(xiàn)如下:

import requests
from urllib.parse import quote
import re

lua = """
function main(splash, args)
  local treat = require("treat")
  local response = splash:http_get("http://httpbin.org/get")
  return treat.as_string(response.body)
end
"""

url = "http://splash:8050/execute?lua_source=" + quote(lua)
response = requests.get(url, auth=("admin", "admin"))
ip = re.search("(d+.d+.d+.d+)", response.text).group(1)
print(ip)

這里的 URL 中的 splash 請自行替換成自己的 Nginx 服務(wù)器 IP,在這里我修改了 Hosts 添加了 splash 別名。

多次運行代碼之后可以發(fā)現(xiàn)每次請求的 IP 都會變化:

如第一次的結(jié)果:

41.159.27.223

第二次的結(jié)果:

41.159.27.9

這就說明負(fù)載均衡已經(jīng)成功實現(xiàn)了。

9. 結(jié)語

到現(xiàn)在為止,我們就可以用 Python 和 Splash 實現(xiàn)JavaScript 渲染的頁面的抓取了,除了 Selenium,本節(jié)所說的 Splash 同樣可以做到非常強(qiáng)大的渲染功能,同時它也不需要瀏覽器即可渲染,使用非常方便。

本節(jié)我們還成功實現(xiàn)了負(fù)載均衡的配置,配置了負(fù)載均衡之后可以多個 Splash 服務(wù)共同合作,減輕單個服務(wù)的負(fù)載,還是比較有用的。

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/44107.html

相關(guān)文章

  • Python3網(wǎng)絡(luò)爬蟲實戰(zhàn)---37、動態(tài)渲染頁面抓取:Selenium

    摘要:不過動態(tài)渲染的頁面不止這一種。再有淘寶這種頁面,它即使是獲取的數(shù)據(jù),但是其接口含有很多加密參數(shù),我們難以直接找出其規(guī)律,也很難直接分析來抓取。我們用一個實例來感受一下在這里們依然是先打開知乎頁面,然后獲取提問按鈕這個節(jié)點,再將其 上一篇文章:Python3網(wǎng)絡(luò)爬蟲實戰(zhàn)---36、分析Ajax爬取今日頭條街拍美圖下一篇文章:Python3網(wǎng)絡(luò)爬蟲實戰(zhàn)---38、動態(tài)渲染頁面抓取:Spla...

    zhjx922 評論0 收藏0
  • Python3網(wǎng)絡(luò)爬蟲實戰(zhàn)---17、爬蟲基本原理

    摘要:在前面我們講到了和的概念,我們向網(wǎng)站的服務(wù)器發(fā)送一個,返回的的便是網(wǎng)頁源代碼。渲染頁面有時候我們在用或抓取網(wǎng)頁時,得到的源代碼實際和瀏覽器中看到的是不一樣的。所以使用基本請求庫得到的結(jié)果源代碼可能跟瀏覽器中的頁面源代碼不太一樣。 上一篇文章:Python3網(wǎng)絡(luò)爬蟲實戰(zhàn)---16、Web網(wǎng)頁基礎(chǔ)下一篇文章:Python3網(wǎng)絡(luò)爬蟲實戰(zhàn)---18、Session和Cookies 爬蟲,即網(wǎng)...

    hellowoody 評論0 收藏0
  • Python3網(wǎng)絡(luò)爬蟲實戰(zhàn)---11、爬蟲框架安裝:ScrapySplash、ScrapyRedi

    摘要:上一篇文章網(wǎng)絡(luò)爬蟲實戰(zhàn)爬蟲框架的安裝下一篇文章網(wǎng)絡(luò)爬蟲實戰(zhàn)部署相關(guān)庫的安裝的安裝是一個中支持渲染的工具,本節(jié)來介紹一下它的安裝方式。另外一個是的庫的安裝,安裝之后即可在中使用服務(wù)。 上一篇文章:Python3網(wǎng)絡(luò)爬蟲實戰(zhàn)---10、爬蟲框架的安裝:PySpider、Scrapy下一篇文章:Python3網(wǎng)絡(luò)爬蟲實戰(zhàn)---12、部署相關(guān)庫的安裝:Docker、Scrapyd Scrap...

    harryhappy 評論0 收藏0
  • Python3網(wǎng)絡(luò)爬蟲實戰(zhàn)---36、分析Ajax爬取今日頭條街拍美圖

    摘要:上一篇文章網(wǎng)絡(luò)爬蟲實戰(zhàn)數(shù)據(jù)爬取下一篇文章網(wǎng)絡(luò)爬蟲實戰(zhàn)動態(tài)渲染頁面抓取本節(jié)我們以今日頭條為例來嘗試通過分析請求來抓取網(wǎng)頁數(shù)據(jù)的方法,我們這次要抓取的目標(biāo)是今日頭條的街拍美圖,抓取完成之后將每組圖片分文件夾下載到本地保存下來。 上一篇文章:Python3網(wǎng)絡(luò)爬蟲實戰(zhàn)---35、 Ajax數(shù)據(jù)爬取下一篇文章:Python3網(wǎng)絡(luò)爬蟲實戰(zhàn)---37、動態(tài)渲染頁面抓取:Selenium 本節(jié)我們...

    Leck1e 評論0 收藏0
  • Python3網(wǎng)絡(luò)爬蟲實戰(zhàn)---35、 Ajax數(shù)據(jù)爬取

    摘要:所以說,我們所看到的微博頁面的真實數(shù)據(jù)并不是最原始的頁面返回的,而是后來執(zhí)行后再次向后臺發(fā)送了請求,拿到數(shù)據(jù)后再進(jìn)一步渲染出來的。結(jié)果提取仍然是拿微博為例,我們接下來用來模擬這些請求,把馬云發(fā)過的微博爬取下來。 上一篇文章:Python3網(wǎng)絡(luò)爬蟲實戰(zhàn)---34、數(shù)據(jù)存儲:非關(guān)系型數(shù)據(jù)庫存儲:Redis下一篇文章:Python3網(wǎng)絡(luò)爬蟲實戰(zhàn)---36、分析Ajax爬取今日頭條街拍美圖 ...

    Thanatos 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<