最近有一个小需求,需要根据用户输入的某宝的店铺 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 的性能消耗。

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

phantomjs 爬去动态页面的更多相关文章

  1. selenium+phantomjs爬取动态页面数据

    1.安装selenium pip/pip3 install selenium 注意依赖关系 2.phantomjs for windows 下载地址:http://phantomjs.org/down ...

  2. Scrapy 爬取动态页面

    目前绝大多数的网站的页面都是冬天页面,动态页面中的部分内容是浏览器运行页面中的JavaScript 脚本动态生成的,爬取相对比较困难 先来看一个很简单的动态页面的例子,在浏览器中打开 http://q ...

  3. Python 爬虫实例(8)—— 爬取 动态页面

    今天使用python 和selenium爬取动态数据,主要是通过不停的更新页面,实现数据的爬取,要爬取的数据如下图 源代码: #-*-coding:utf-8-*- import time from ...

  4. selenium + PhantomJS 爬取js页面

    from selenium import webdriver import time _url="http://xxxxxxxx.com" driver = webdriver.P ...

  5. selenium自动化测试爬取动态页面大全

    目录 一:浏览器信息测试 二:查找结点 三:测试动作 四:获取节点信息 五:切换子页面Frame 六,延时请求 七:前进和后退 八:Cookies 八:选项卡处理 九:捕获异常   这里之讲解用法,安 ...

  6. 爬虫系列5:scrapy动态页面爬取的另一种思路

    前面有篇文章给出了爬取动态页面的一种思路,即应用Selenium+Firefox(参考<scrapy动态页面爬取>).但是selenium需要运行本地浏览器,比较耗时,不太适合大规模网页抓 ...

  7. scrapy使用PhantomJS爬取数据

    环境:python2.7+scrapy+selenium+PhantomJS 内容:测试scrapy+PhantomJS 爬去内容:涉及到js加载更多的页面 原理:配置文件打开中间件+修改proces ...

  8. Python+Selenium爬取动态加载页面(1)

    注: 最近有一小任务,需要收集水质和水雨信息,找了两个网站:国家地表水水质自动监测实时数据发布系统和全国水雨情网.由于这两个网站的数据都是动态加载出来的,所以我用了Selenium来完成我的数据获取. ...

  9. phantomjs+selenium实现爬取动态网址

    之前使用 selenium + firefox驱动浏览器来实现爬取动态网址,但是firefox经常更新,更新后时常会导致webdriver启动不来,所以改用phantomjs+selenium来改善一 ...

随机推荐

  1. FFmpeg源代码简单分析:avformat_find_stream_info()

    ===================================================== FFmpeg的库函数源代码分析文章列表: [架构图] FFmpeg源代码结构图 - 解码 F ...

  2. Android中PropertyAnimation属性动画详解(一)

    在之前的文章中已经讲了帧动画frame-by-frame animation和补间动画tweened animation,其实这两种动画原理好简单,都是按照预先固定的动画模式来播放的,帧动画将一张张单 ...

  3. 18 UI美化状态集合的位图selector

    当我们某个控件 想在不同状态下显示不同的背景图的需求 如我们需要按钮在正常状态显示一种图 按下显示另一背景图 或者单选框被选中时是一种显示图片 没选中是另一种背景图 例子 按钮在不同状态显示不同的背景 ...

  4. 人类创造未来的思想先锋:这些 TED 演示深深震撼着我们

    今年亮点之一是谷歌创始人拉里佩奇的演讲.他有一个核心观点:特别成功的公司,是那些敢于想象未来,并付出行动创造未来的公司.这听上去是老生常谈,但又确实是个真理.他实际上想说预测未来的最好方式就是创造它, ...

  5. 后端分布式系列:分布式存储-MySQL 数据库事务与复制

    好久没有写技术文章了,因为一直在思考 「后端分布式」这个系列到底怎么写才合适.最近基本想清楚了,「后端分布式」包括「分布式存储」和 「分布式计算」两大类.结合实际工作中碰到的问题,以寻找答案的方式来剖 ...

  6. AsyncTask(异步任务)讲解-android的学习之旅(四十六)

    AsyncTask简介 Android的UI线程主要处理用户的按键,触屏和View的绘制等,不能在里面处理耗时的操作,否则会出现ANR,因此耗时的操作要单独开一个线程处理,但是新线程不能直接处理UI线 ...

  7. JPA(三)之实体关系一对多(多对一)

     1.背景介绍: 对于购买商品时,订单信息(Order)和订单商品信息(OrderItem)的关系就是一对多的关系. 2.实体bean: Order.java代码 ? 1 2 3 4 5 6 7 ...

  8. Android学习之Animation(二)

    接着上次的View Animation动画,这次是Frame Animation.具体点来讲就是在Frame层面上进行变化的动画效果的设置.说白了就是定时更换"背景"图.来实现不同 ...

  9. Cocos2D:塔防游戏制作之旅(十二)

    以上代码块相当直观 - 但是它分解的有些细致了. 首先,敌人通过传递HelloWorldLayer对象的引用而初始化.在init方法里,少数重要的变量被设置: maxHP:定义敌人有多经打(Tough ...

  10. 【翻译】使用Sencha Ext JS 6打造通用应用程序

    原文:Using Sencha Ext JS 6 to Build Universal Apps {.aligncenter} 在Sencha和整个Ext JS团队的支持下,我很高兴能跟大家分享一下有 ...