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 的性能消耗。

让程序本身一直循环执行,就能够获取到大量的数据啦

相关文章
相关标签/搜索