網絡與節點,phantomjs和騎手一起爬行
鑰匙要點
- >利用node.js和npm有效地為Web爬網和其他命令行任務設置自定義CLI縮影。
> >使用Phantomjs和Horseman軟件包來模擬瀏覽器中的用戶互動,從而增強了自動化的Web爬行功能。 - 結合了騎士方法的鏈接,以執行複雜的動作序列,從而在網頁中進行動態交互。
- 利用騎士中的evaluate()方法直接從DOM中提取靈活的腳本和數據提取,可用於諸如污損檢測之類的任務。
- >利用Horseman的屏幕截圖功能在網上爬行期間捕獲和保存屏幕截圖,以幫助視覺QA測試等任務。
- >確保每次使用後都關閉騎士實例,以防止孤立的phantomjs過程,保持系統性能和穩定性。
- >
可以在GitHub上找到本教程的源代碼。為了運行示例,您需要同時安裝node.js和phantomjs。可以在此處找到用於下載和安裝的說明:node.js,phantomjs。
>設置基本命令行框架任何CLI框架的核心是將命令轉換為一個或多個可選或必需的參數,轉換為具體操作的概念。在這方面非常有用的兩個NPM軟件包是指揮官和提示。
指揮官允許您定義支持哪些參數,同時提示允許您(足夠適當地)提示用戶在運行時輸入。最終結果是一個句法甜蜜的界面,用於基於某些用戶提供的數據,以動態行為執行各種動作。
>說,例如,我們希望我們的命令看起來像這樣:
>$ <span>node run.js -x hello_world </span>
我們的入口點(run.js)定義了這樣的參數:
>program <span>.version('1.0.0') </span> <span>.option('-x --action-to-perform [string]', 'The type of action to perform.') </span> <span>.option('-u --url [string]', 'Optional URL used by certain actions') </span> <span>.parse(process.argv); </span>
並定義了這樣的各種用戶輸入案例:
><span>var performAction = require('./actions/' + program.actionToPerform) </span> <span>switch (program.actionToPerform) { </span> <span>case 'hello_world': </span> prompt<span>.get([{ </span> <span>// What the property name should be in the result object </span> <span>name: 'url', </span> <span>// The prompt message shown to the user </span> <span>description: 'Enter a URL', </span> <span>// Whether or not the user is required to enter a value </span> <span>required: true, </span> <span>// Validates the user input </span> <span>conform: function (value) { </span> <span>// In this case, the user must enter a valid URL </span> <span>return validUrl.isWebUri(value); </span> <span>} </span> <span>}], function (err<span>, result</span>) { </span> <span>// Perform some action following successful input </span> <span>performAction(phantomInstance, result.url); </span> <span>}); </span> <span>break; </span><span>} </span>
>
如您所見,該模塊期望提供一個phantomjs對象(Phantominstance)和URL(URL)的實例。我們將暫時地定義Phantomjs實例的細節,但是目前足以看到我們為觸發特定動作奠定了基礎。既然我們已經制定了一定的慣例,我們可以輕鬆地以定義和理智的方式添加新的動作。<span>'use strict'; </span> <span>/** </span><span> * <span>@param Horseman phantomInstance </span></span><span> * <span>@param string url </span></span><span> */ </span>module<span>.exports = function (phantomInstance<span>, url</span>) { </span> <span>if (!url || typeof url !== 'string') { </span> <span>throw 'You must specify a url to ping'; </span> <span>} else { </span> <span>console.log('Pinging url: ', url); </span> <span>} </span> phantomInstance <span>.open(url) </span> <span>.status() </span> <span>.then(function (statusCode) { </span> <span>if (Number(statusCode) >= 400) { </span> <span>throw 'Page failed with status: ' + statusCode; </span> <span>} else { </span> <span>console.log('Hello world. Status code returned: ', statusCode); </span> <span>} </span> <span>}) </span> <span>.catch(function (err) { </span> <span>console.log('Error: ', err); </span> <span>}) </span> <span>// Always close the Horseman instance </span> <span>// Otherwise you might end up with orphaned phantom processes </span> <span>.close(); </span><span>}; </span>
爬行
>每次我們通過CLI框架觸發操作時,我們的輸入腳本(RUN.JS)實例化騎士實例並將其傳遞到指定的操作模塊。在偽代碼中,它看起來像這樣:
>
現在,當我們運行命令時,騎手實例和輸入URL將傳遞到Hello_world模塊,導致Phantomjs請求URL,捕獲其狀態代碼並將狀態打印到控制台。我們剛剛使用騎馬者進行了第一個真正的善意爬行。 giddyup!
<span>var phantomInstance = new Horseman({ </span> <span>phantomPath: '/usr/local/bin/phantomjs', </span> <span>loadImages: true, </span> <span>injectJquery: true, </span> <span>webSecurity: true, </span> <span>ignoreSSLErrors: true </span><span>}); </span> <span>performAction(phantomInstance, ...); </span>
複合互動的騎士方法
到目前為止,我們已經研究了非常簡單的騎士用法,但是當我們將其方法鏈接在一起以在瀏覽器中執行一系列操作時,包裝可以做得更多。為了演示其中一些功能,讓我們定義一個動作,該操作模擬了通過GitHub導航以創建新存儲庫的用戶。
請注意:此示例純粹是出於演示目的,不應被視為創建GitHub存儲庫的可行方法。這僅僅是一個人如何使用騎手與Web應用程序進行交互的示例。如果您有興趣以自動方式創建存儲庫,則應使用官方的GitHub API。
讓我們假設新的爬網會像這樣觸發:>按照我們已經制定的CLI框架的約定,我們需要在名為create_repo.js的操作目錄中添加一個新模塊。與我們以前的“ Hello World”示例一樣,create_repo模塊導出一個包含該動作的所有邏輯的單個函數。
$ <span>node run.js -x hello_world </span>
請注意,在此操作中,我們將更多的參數傳遞給導出的函數,而不是以前。這些參數包括用戶名,密碼和存儲庫。一旦用戶成功完成了及時挑戰,我們將從run.js傳遞這些值。
program <span>.version('1.0.0') </span> <span>.option('-x --action-to-perform [string]', 'The type of action to perform.') </span> <span>.option('-u --url [string]', 'Optional URL used by certain actions') </span> <span>.parse(process.argv); </span>
>現在我們將此掛鉤添加到run.js,當用戶輸入相關數據時,它將傳遞給操作,從而使我們可以繼續進行爬網。
至於Create_repo爬網邏輯本身,我們使用騎手的方法來導航到GitHub登錄頁面,輸入提供的用戶名和密碼,然後提交表單:<span>var performAction = require('./actions/' + program.actionToPerform) </span> <span>switch (program.actionToPerform) { </span> <span>case 'hello_world': </span> prompt<span>.get([{ </span> <span>// What the property name should be in the result object </span> <span>name: 'url', </span> <span>// The prompt message shown to the user </span> <span>description: 'Enter a URL', </span> <span>// Whether or not the user is required to enter a value </span> <span>required: true, </span> <span>// Validates the user input </span> <span>conform: function (value) { </span> <span>// In this case, the user must enter a valid URL </span> <span>return validUrl.isWebUri(value); </span> <span>} </span> <span>}], function (err<span>, result</span>) { </span> <span>// Perform some action following successful input </span> <span>performAction(phantomInstance, result.url); </span> <span>}); </span> <span>break; </span><span>} </span>
我們通過等待表單提交頁面加載來繼續鏈條:
之後,我們使用jQuery來確定登錄是否成功:
<span>'use strict'; </span> <span>/** </span><span> * <span>@param Horseman phantomInstance </span></span><span> * <span>@param string url </span></span><span> */ </span>module<span>.exports = function (phantomInstance<span>, url</span>) { </span> <span>if (!url || typeof url !== 'string') { </span> <span>throw 'You must specify a url to ping'; </span> <span>} else { </span> <span>console.log('Pinging url: ', url); </span> <span>} </span> phantomInstance <span>.open(url) </span> <span>.status() </span> <span>.then(function (statusCode) { </span> <span>if (Number(statusCode) >= 400) { </span> <span>throw 'Page failed with status: ' + statusCode; </span> <span>} else { </span> <span>console.log('Hello world. Status code returned: ', statusCode); </span> <span>} </span> <span>}) </span> <span>.catch(function (err) { </span> <span>console.log('Error: ', err); </span> <span>}) </span> <span>// Always close the Horseman instance </span> <span>// Otherwise you might end up with orphaned phantom processes </span> <span>.close(); </span><span>}; </span>
>在我們的個人資料頁面上,我們將導航到我們的存儲庫標籤:
<span>var phantomInstance = new Horseman({ </span> <span>phantomPath: '/usr/local/bin/phantomjs', </span> <span>loadImages: true, </span> <span>injectJquery: true, </span> <span>webSecurity: true, </span> <span>ignoreSSLErrors: true </span><span>}); </span> <span>performAction(phantomInstance, ...); </span>
在我們的存儲庫選項卡時,我們檢查是否已經存在帶有指定名稱的存儲庫。如果是這樣,那麼我們會丟下錯誤。如果不是,那麼我們繼續我們的順序:
$ <span>node run.js -x create_repo </span>
假設沒有錯誤,我們通過編程單擊“新存儲庫”按鈕並等待下一頁:
module<span>.exports = function (phantomInstance<span>, username, password, repository</span>) { </span> <span>if (!username || !password || !repository) { </span> <span>throw 'You must specify login credentials and a repository name'; </span> <span>} </span> <span>... </span><span>} </span>
之後,我們輸入提供的存儲庫名稱並提交表格:
<span>switch (program.actionToPerform) { </span> <span>case 'create_repo': </span> prompt<span>.get([{ </span> <span>name: 'repository', </span> <span>description: 'Enter repository name', </span> <span>required: true </span> <span>}, { </span> <span>name: 'username', </span> <span>description: 'Enter GitHub username', </span> <span>required: true </span> <span>}, { </span> <span>name: 'password', </span> <span>description: 'Enter GitHub password', </span> <span>hidden: true, </span> <span>required: true </span> <span>}], function (err<span>, result</span>) { </span> <span>performAction( </span> phantomInstance<span>, </span> result<span>.username, </span> result<span>.password, </span> result<span>.repository </span> <span>); </span> <span>}); </span> <span>break; </span> <span>... </span>
與任何騎馬爬行一樣,至關重要的是,我們結束了騎馬的實例:
phantomInstance <span>.open('https://github.com/login') </span> <span>.type('input[name="login"]', username) </span> <span>.type('input[name="password"]', password) </span> <span>.click('input[name="commit"]') </span>
>未能關閉騎士實例可能會導致機器上的孤立phantomjs處理。
<span>.waitForNextPage() </span>
在這一點上,我們已經組裝了一系列靜態序列,以編程方式在GitHub上創建一個新的存儲庫。為此,我們鏈接了一系列的騎手方法。
這種方法對於事先已知的特定結構和行為模式可能很有用,但是,您可能會發現您需要在某個時候實現更靈活的腳本。如果您的動作序列有可能根據上下文變化或產生多個不同的結果,則可能是這種情況。如果您需要從DOM中提取數據,也將是這種情況。
在這種情況下,您可以使用Horseman的evaliate()方法,它允許您通過注入內聯或外部鏈接JavaScript來執行瀏覽器中的自由形式交互。>
>本節演示了從頁面中提取基本數據的示例(在這種情況下,錨點鏈接)。可能需要這種情況的一種情況是構建一個污損檢測軌,以擊中域上的每個URL。與我們的最後一個示例一樣,我們必須首先在操作目錄中添加一個新模塊:
,然後在run.js中為新操作添加一個鉤子:
$ <span>node run.js -x hello_world </span>
現在,此代碼已經到位,我們可以通過運行以下命令來從任何給定的頁面提取鏈接:
program <span>.version('1.0.0') </span> <span>.option('-x --action-to-perform [string]', 'The type of action to perform.') </span> <span>.option('-u --url [string]', 'Optional URL used by certain actions') </span> <span>.parse(process.argv); </span>
>此操作演示了從頁面上提取數據,並且不會利用騎手內置的任何瀏覽器操作。它直接執行您在estuation()方法中放置的任何JavaScript,並且會像在瀏覽器環境中本地運行一樣。
><span>var performAction = require('./actions/' + program.actionToPerform) </span> <span>switch (program.actionToPerform) { </span> <span>case 'hello_world': </span> prompt<span>.get([{ </span> <span>// What the property name should be in the result object </span> <span>name: 'url', </span> <span>// The prompt message shown to the user </span> <span>description: 'Enter a URL', </span> <span>// Whether or not the user is required to enter a value </span> <span>required: true, </span> <span>// Validates the user input </span> <span>conform: function (value) { </span> <span>// In this case, the user must enter a valid URL </span> <span>return validUrl.isWebUri(value); </span> <span>} </span> <span>}], function (err<span>, result</span>) { </span> <span>// Perform some action following successful input </span> <span>performAction(phantomInstance, result.url); </span> <span>}); </span> <span>break; </span><span>} </span>
>通過擴展上面的邏輯,您幾乎可以在任何網站上執行任何操作。
><span>'use strict'; </span> <span>/** </span><span> * <span>@param Horseman phantomInstance </span></span><span> * <span>@param string url </span></span><span> */ </span>module<span>.exports = function (phantomInstance<span>, url</span>) { </span> <span>if (!url || typeof url !== 'string') { </span> <span>throw 'You must specify a url to ping'; </span> <span>} else { </span> <span>console.log('Pinging url: ', url); </span> <span>} </span> phantomInstance <span>.open(url) </span> <span>.status() </span> <span>.then(function (statusCode) { </span> <span>if (Number(statusCode) >= 400) { </span> <span>throw 'Page failed with status: ' + statusCode; </span> <span>} else { </span> <span>console.log('Hello world. Status code returned: ', statusCode); </span> <span>} </span> <span>}) </span> <span>.catch(function (err) { </span> <span>console.log('Error: ', err); </span> <span>}) </span> <span>// Always close the Horseman instance </span> <span>// Otherwise you might end up with orphaned phantom processes </span> <span>.close(); </span><span>}; </span>
>我想證明的最終用例是您將如何使用Horseman拍攝屏幕截圖。我們可以使用Horseman的ScreenShotBase64()方法來完成此操作,該方法返回代表屏幕截圖的base64編碼字符串。
與我們上一個示例一樣,我們必須首先在操作目錄中添加一個新模塊:
,然後在run.js中為新操作添加一個鉤子:
>
<span>var phantomInstance = new Horseman({ </span> <span>phantomPath: '/usr/local/bin/phantomjs', </span> <span>loadImages: true, </span> <span>injectJquery: true, </span> <span>webSecurity: true, </span> <span>ignoreSSLErrors: true </span><span>}); </span> <span>performAction(phantomInstance, ...); </span>
>
$ <span>node run.js -x create_repo </span>
>
如果要保存實際映像,則使用屏幕截圖()方法。module<span>.exports = function (phantomInstance<span>, username, password, repository</span>) { </span> <span>if (!username || !password || !repository) { </span> <span>throw 'You must specify login credentials and a repository name'; </span> <span>} </span> <span>... </span><span>} </span>
結論
本教程試圖展示自定義的CLI微框架和一些基本的邏輯,用於使用Horseman軟件包來利用Phantomjs,以爬Node.js爬網。雖然使用CLI框架可能會使許多項目受益,但爬行通常僅限於非常特定的問題域。一個共同的領域是質量保證(QA),可以將爬網用於功能和用戶界面測試。另一個領域是安全性,例如,您可能想定期爬網,以檢測到它是否已被污損或折衷。
>無論您的項目可能是什麼情況,請確保清楚地定義您的目標並儘可能不引人注目。在可能的情況下獲得許可,請在最大程度上禮貌,並註意永遠不要DDOS。如果您懷疑自己正在產生大量的自動流量,那麼您可能會重新評估您的目標,實施或許可水平。
經常詢問的問題(常見問題解答)有關網絡爬行的節點和phantomjs騎手Web爬網和Web刮擦之間有什麼區別?
Web爬網和Web刮擦是兩個不同的過程,儘管它們通常可以互換使用。網絡爬行是系統瀏覽網絡的過程,通常由機器人或蜘蛛進行。它涉及索引網站的內容和以下鏈接到其他網頁。另一方面,網絡刮擦是從網站提取特定數據的過程。它涉及解析網頁的HTML以刪除所需的數據。雖然網絡爬網是關於導航和索引的,但網絡刮擦是關於數據提取的。
異步性質。它允許並發處理,這意味著您可以同時爬網多頁。這使其比同步執行的其他語言要快得多。此外,Node.js擁有一個豐富的生態系統,具有許多可以幫助網絡爬行的庫和工具,例如Phantomjs Horseman。 > Phantomjs Horseman是一個Node.js軟件包,可為使用Phantomjs自動化Web瀏覽器提供高級API。它允許您在網頁上執行操作,例如單擊鏈接,填寫表單和屏幕截圖。這使其成為網絡爬網的強大工具,因為它使您可以像人類用戶一樣與網頁進行交互。
> JavaScript渲染如何影響Web爬行? >>我可以使用Web爬網來監視網站上的更改嗎? ,網絡爬行可用於監視網站上的更改。通過定期爬行網站並將當前狀態與以前的狀態進行比較,您可以檢測任何更改。這對於各種目的可能很有用,例如在電子商務網站上跟踪價格變化或監視新聞網站上的更新。
網絡爬行法律?
>>網絡爬行的合法性取決於在包括您所處的管轄權以及您爬行的特定網站上的幾個因素上。一些網站明確允許Web在其robots.txt文件中爬行,而另一些網站則禁止Web爬網。重要的是要尊重網站的robots.txt文件,並且不要在短時間內用太多請求超載網站的服務器。 >
>我如何優化我的網絡爬行過程?是優化網絡爬行過程的幾種方法。一種方法是使用廣度優先搜索(BFS)算法,該算法可確保您在進入下一個深度級別之前,在一定深度爬網。另一種方法是根據頁面的相關性優先考慮爬網。例如,如果您要抓取電子商務網站,您可能想在博客文章之前爬網。 >是的,使用Phantomjs Horseman,您可以自動登錄網站的過程。這使您可以在登錄後訪問僅訪問的頁面。但是,您應該意識到這可能違反網站的服務條款。 我如何處理網絡爬網中的動態內容? >處理動態內容在Web Crawling中可能具有挑戰性,作為傳統Web爬網僅解析網頁的靜態HTML。但是,使用Phantomjs Horseman之類的工具,您可以像人類用戶一樣渲染JavaScript並與動態內容進行交互。這使您可以從嚴重依賴JavaScript進行內容生成的網站上爬網和提取數據。 >>如何阻止我的網絡爬行者被阻塞?一種方法是尊重網站的robots.txt文件,該文件提供了有關您允許爬網的哪些部分的指南。另一種方法是限制您將請求發送到網站的速率,以避免服務器超載。您也可以旋轉IP地址和用戶代理以避免被檢測為機器人。 >
>我可以使用Web爬網來監視網站上的更改嗎? ,網絡爬行可用於監視網站上的更改。通過定期爬行網站並將當前狀態與以前的狀態進行比較,您可以檢測任何更改。這對於各種目的可能很有用,例如在電子商務網站上跟踪價格變化或監視新聞網站上的更新。
網絡爬行法律?
>>網絡爬行的合法性取決於在包括您所處的管轄權以及您爬行的特定網站上的幾個因素上。一些網站明確允許Web在其robots.txt文件中爬行,而另一些網站則禁止Web爬網。重要的是要尊重網站的robots.txt文件,並且不要在短時間內用太多請求超載網站的服務器。 >
>我如何優化我的網絡爬行過程?是優化網絡爬行過程的幾種方法。一種方法是使用廣度優先搜索(BFS)算法,該算法可確保您在進入下一個深度級別之前,在一定深度爬網。另一種方法是根據頁面的相關性優先考慮爬網。例如,如果您要抓取電子商務網站,您可能想在博客文章之前爬網。 >是的,使用Phantomjs Horseman,您可以自動登錄網站的過程。這使您可以在登錄後訪問僅訪問的頁面。但是,您應該意識到這可能違反網站的服務條款。 我如何處理網絡爬網中的動態內容?>處理動態內容在Web Crawling中可能具有挑戰性,作為傳統Web爬網僅解析網頁的靜態HTML。但是,使用Phantomjs Horseman之類的工具,您可以像人類用戶一樣渲染JavaScript並與動態內容進行交互。這使您可以從嚴重依賴JavaScript進行內容生成的網站上爬網和提取數據。 >>如何阻止我的網絡爬行者被阻塞?一種方法是尊重網站的robots.txt文件,該文件提供了有關您允許爬網的哪些部分的指南。另一種方法是限制您將請求發送到網站的速率,以避免服務器超載。您也可以旋轉IP地址和用戶代理以避免被檢測為機器人。 >
>如何阻止我的網絡爬行者被阻塞?一種方法是尊重網站的robots.txt文件,該文件提供了有關您允許爬網的哪些部分的指南。另一種方法是限制您將請求發送到網站的速率,以避免服務器超載。您也可以旋轉IP地址和用戶代理以避免被檢測為機器人。 >
以上是網絡與節點,phantomjs和騎手一起爬行的詳細內容。更多資訊請關注PHP中文網其他相關文章!

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

JavaScript是現代Web開發的基石,它的主要功能包括事件驅動編程、動態內容生成和異步編程。 1)事件驅動編程允許網頁根據用戶操作動態變化。 2)動態內容生成使得頁面內容可以根據條件調整。 3)異步編程確保用戶界面不被阻塞。 JavaScript廣泛應用於網頁交互、單頁面應用和服務器端開發,極大地提升了用戶體驗和跨平台開發的靈活性。

JavaScript的最新趨勢包括TypeScript的崛起、現代框架和庫的流行以及WebAssembly的應用。未來前景涵蓋更強大的類型系統、服務器端JavaScript的發展、人工智能和機器學習的擴展以及物聯網和邊緣計算的潛力。

不同JavaScript引擎在解析和執行JavaScript代碼時,效果會有所不同,因為每個引擎的實現原理和優化策略各有差異。 1.詞法分析:將源碼轉換為詞法單元。 2.語法分析:生成抽象語法樹。 3.優化和編譯:通過JIT編譯器生成機器碼。 4.執行:運行機器碼。 V8引擎通過即時編譯和隱藏類優化,SpiderMonkey使用類型推斷系統,導致在相同代碼上的性能表現不同。

Python更適合初學者,學習曲線平緩,語法簡潔;JavaScript適合前端開發,學習曲線較陡,語法靈活。 1.Python語法直觀,適用於數據科學和後端開發。 2.JavaScript靈活,廣泛用於前端和服務器端編程。

JavaScript是現代Web開發的核心語言,因其多樣性和靈活性而廣泛應用。 1)前端開發:通過DOM操作和現代框架(如React、Vue.js、Angular)構建動態網頁和單頁面應用。 2)服務器端開發:Node.js利用非阻塞I/O模型處理高並發和實時應用。 3)移動和桌面應用開發:通過ReactNative和Electron實現跨平台開發,提高開發效率。

本文展示了與許可證確保的後端的前端集成,並使用Next.js構建功能性Edtech SaaS應用程序。 前端獲取用戶權限以控制UI的可見性並確保API要求遵守角色庫

我使用您的日常技術工具構建了功能性的多租戶SaaS應用程序(一個Edtech應用程序),您可以做同樣的事情。 首先,什麼是多租戶SaaS應用程序? 多租戶SaaS應用程序可讓您從唱歌中為多個客戶提供服務

從C/C 轉向JavaScript需要適應動態類型、垃圾回收和異步編程等特點。 1)C/C 是靜態類型語言,需手動管理內存,而JavaScript是動態類型,垃圾回收自動處理。 2)C/C 需編譯成機器碼,JavaScript則為解釋型語言。 3)JavaScript引入閉包、原型鍊和Promise等概念,增強了靈活性和異步編程能力。
