返回介绍

18.6 PySpider 和 PhantomJS

发布于 2024-01-26 22:39:51 字数 2629 浏览 0 评论 0 收藏 0

除了模拟Ajax请求来突破动态网站之外,PhantomJS也是一个不错的选择,PySpider对PhantomJS提供了很好的支持,而且使用简单。

18.6.1 使用PhantomJS

在使用PhantomJS之前,首先确保已经正确安装了PhantomJS,而且安装路径配置到Path环境变量中,这些内容已经在第9章讲过。

当你在运行PySpider命令时,启动的是all模式,也就是在命令行中输入:pyspider all。这时候PhantomJS已经启动,这一点通过查看当前进程可以发现。使用PhantomJS时,我们只需要在crawl方法中添加fetch_type='js'参数即可。我们可以对比一下使用前与使用后的不同,以MTime电影网为例,还是观察电影评分的位置。提前创建一个MTime项目,在默认代码基础上将起始URL换成http://movie.mtime.com/217130/:

  from pyspider.libs.base_handler import *
  class Handler(BaseHandler):
     crawl_config = {
     }
     @every(minutes=24 * 60)
     def on_start(self):
       self.crawl('http://movie.mtime.com/217130/', callback=self.index_page)
  
     @config(age=10 * 24 * 60 * 60)
     def index_page(self, response):
       for each in response.doc('a[href^="http"]').items():
            self.crawl(each.attr.href, callback=self.detail_page)
  
     @config(priority=2)
     def detail_page(self, response):
       return {
            "url": response.url,
            "title": response.doc('title').text(),
       }

保存代码并运行,如图18-16所示,在Web预览界面,我们看到是没有票房和评分信息的页面。

这个时候,我们在crawl方法中添加fetch_type='js',修改如下:

  self.crawl('http://movie.mtime.com/217130/', fetch_type='js', callback=self.index_
     page)

保存代码并运行,如图18-17所示,在web预览界面,我们已经看到完整的票房和评分信息的页面。

在渲染之后的页面上,使用enable css selector helper功能就可以直接获取选定元素的CSS表达式。

图18-16 无PhantomJS渲染

图18-17 PhantomJS渲染

18.6.2 运行JavaScript

不知道大家是否还记得,在第9章爬取去哪网时,两次加载才能获取当前页面完整的数据,采取的措施是执行js代码:window.scrollTo(0,document.body.scrollHeight);,将页面滑到底部实现第二次加载,PySpider也提供了接口来实现js脚本的执行,通过在crawl基础上额外添加js_script的方式。示例代码如下:

  class Handler(BaseHandler):
     def on_start(self):
       self.crawl('http://www.pinterest.com/categories/popular/',
            fetch_type='js', js_script="""
            function() {
              window.scrollTo(0,document.body.scrollHeight);
            }
            """, callback=self.index_page)
     def index_page(self, response):
       return {
            "url": response.url,
            "images": [{
              "title": x('.richPinGridTitle').text(),
              "img": x('.pinImg').attr('src'),
              "author": x('.creditName').text(),
            } for x in response.doc('.item').items() if x('.pinImg')]
       }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文