phantomjs 爬去動態頁面

最近有一個小需求,須要根據用戶輸入的某寶的店鋪 url,檢查地址是否存在,並抓取店鋪名稱。某寶店鋪 url 的 title 一般是 xx-xx-xx 的形式,中間的 xx 就是對應的店鋪名稱。html

這個需求很簡單,根據 url 直接發送 get 請求,利用 cheerio 解析獲得的 html 文件,就能夠得到 title 的內容,再切割字符串就能夠得到店鋪名稱。git

爲了驗證某寶店鋪頁面的 title 均是 xx-xx-xx 形式,而且中間的 xx 就是店鋪名稱,就要搜索大量店鋪頁面名稱。一個個查看即耗時間也不實際,因而決定利用爬蟲快速獲取店鋪名稱。其實爬蟲的基本思路並不難,更重要的在於分析頁面結構,以獲取須要的內容。github

頁面大體分爲3種狀況:web

① 直出頁面,獲取到 html 文件就能夠解析須要的內容瀏覽器

② 動態頁面,所需內容是數據經過接口得到的,直接請求接口便可併發

③ 動態頁面,找不到相關數據接口,藉助 PhantomJS 獲取完整的頁面性能

 

怎樣能快速得到大量的店鋪 url 呢?某寶的寶貝列表中,寶貝信息實際上是包含了該寶貝所在店鋪首頁的連接,經過寶貝列表就能夠快速得到店鋪 url。經過分析頁面,很不幸,寶貝列表是腳本動態加載的,而且找不到相關數據的接口,惟有藉助 PhantomJS 了。PhantomJS 雖然強大,但性能並非很好,不過爲了知足個人好奇心,足夠了。lua

 

PhantomJSurl

PhantomJS 是一個 webkit 的 JavaScript API,至關於一個閹割版的瀏覽器,詳情可查看官網spa

PhantomJS 獲取並解析頁面的語法也很簡單,完整demo

// page。open 打開並加載 url,這裏的 url 爲寶貝列表頁面
page.open(url, function (s) {   console.log('index ' + index + ' ' + s)   if (s === 'success') {     setTimeout(function () {
      // page.evaluate 用於解析頁面內容,詳情請看官網         const shopUrl
= page.evaluate(function () {         const urls = []         const ele = document.getElementsByClassName('J_ShopInfo')         for(var i = 0, len = ele.length; i < len; ++i) {           const item = ele[i]           urls.push(item.href)         }         return urls       })       getTitle(shopUrl, 0, getShopsName(index + 44, max))     }, 1500)   } })
getTitle 用於獲取店鋪首頁 url 的 title
function getTitle (urls, i, cb) {
    if (i < urls.length) {
        const url = urls[i]
        page.open(url, function(s) {
            if (s === 'success') {
                const result = page.evaluate(function () {
                    return document.title
                })
                console.log(i + ' ' + result)
                titles.push(result)
                getTitle (urls, i + 1, cb)
            }
        })
    } else {
        cb && cb()
    }
}

 

在訪問寶貝列表頁面和店鋪頁面時,因爲某寶的反爬蟲措施,這裏都用了遞歸搜索,確保不是併發請求頁面,不然頁面會獲取失敗。setTimeout 是爲了等待頁面中所需內容已加載後再解析。若是獲取到頁面後當即解析,只會獲得一個幾乎空白的頁面。

因爲頁面都包含大量的圖片信息,能夠經過設置

page.settings.loadImages = false

不加載內聯圖片,減小 PhantomJS 的性能消耗。

讓程序本身一直循環執行,就能夠獲取到大量的數據啦

相關文章
相關標籤/搜索