zoukankan      html  css  js  c++  java
  • phantomjs 爬去动态页面

    最近有一个小需求,需要根据用户输入的某宝的店铺 url,检查地址是否存在,并抓取店铺名称。某宝店铺 url 的 title 通常是 xx-xx-xx 的形式,中间的 xx 就是对应的店铺名称。

    这个需求很简单,根据 url 直接发送 get 请求,利用 cheerio 解析得到的 html 文件,就可以获得 title 的内容,再切割字符串就可以获得店铺名称。

    为了验证某宝店铺页面的 title 均是 xx-xx-xx 形式,并且中间的 xx 就是店铺名称,就要搜索大量店铺页面名称。一个个查看即耗时间也不实际,于是决定利用爬虫快速获取店铺名称。其实爬虫的基本思路并不难,更重要的在于分析页面结构,以获取需要的内容。

    页面大致分为3种情况:

    ① 直出页面,获取到 html 文件就可以解析需要的内容

    ② 动态页面,所需内容是数据通过接口获得的,直接请求接口即可

    ③ 动态页面,找不到相关数据接口,借助 PhantomJS 获取完整的页面

    怎样能快速获得大量的店铺 url 呢?某宝的宝贝列表中,宝贝信息其实是包含了该宝贝所在店铺首页的链接,通过宝贝列表就可以快速获得店铺 url。通过分析页面,很不幸,宝贝列表是脚本动态加载的,并且找不到相关数据的接口,唯有借助 PhantomJS 了。PhantomJS 虽然强大,但性能并不是很好,不过为了满足我的好奇心,足够了。

    PhantomJS

    PhantomJS 是一个 webkit 的 JavaScript API,相当于一个阉割版的浏览器,详情可查看官网

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

    让程序自己一直循环执行,就可以获取到大量的数据啦

  • 相关阅读:
    多色图标字体
    css编写规则BEM
    css处理工具PostCss
    vue2.0点击其他任何地方隐藏dom
    vue2.0多页面开发
    Dijkstra算法(邻接矩阵存储)
    kmp算法c++代码实现
    最小生成树(prim算法,Kruskal算法)c++实现
    字符串匹配的KMP算法(转)
    筛选法求素数
  • 原文地址:https://www.cnblogs.com/xxhuan/p/8982740.html
Copyright © 2011-2022 走看看