在Python中使用CasperJS获取JS渲染生成的HTML内容的教程


Posted in Python onApril 09, 2015

文章摘要:其实这里casperjs与python没有直接关系,主要依赖casperjs调用phantomjs webkit获取html文件内容。长期以来,爬虫抓取 客户端javascript渲染生成的html页面 都极为 困难, Java里面有 HtmlUnit, 而Python里,我们可以使用独立的跨平台的CasperJS。

    创建site.js(接口文件,输入:url,输出:html file)  

//USAGE: E:\toolkit\n1k0-casperjs-e3a77d0\bin>python casperjs site.js --url=http://spys.ru/free-proxy-list/IE/ --outputfile='temp.html' 
     
    var fs = require('fs'); 
    var casper = require('casper').create({ 
     pageSettings: { 
     loadImages: false,     
     loadPlugins: false,    
     userAgent: 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/34.0.1847.137 Safari/537.36 LBBROWSER' 
    }, 
    logLevel: "debug",//日志等级 
    verbose: true  // 记录日志到控制台 
     }); 
    var url = casper.cli.raw.get('url'); 
    var outputfile = casper.cli.raw.get('outputfile'); 
    //请求页面 
    casper.start(url, function () { 
    fs.write(outputfile, this.getHTML(), 'w'); 
    }); 
     
    casper.run();

    python 代码, checkout_proxy.py      

import json 
    import sys 
    #import requests 
    #import requests.utils, pickle 
    from bs4 import BeautifulSoup 
    import os.path,os 
    import threading 
    #from multiprocessing import Process, Manager 
    from datetime import datetime 
    import traceback 
    import logging 
    import re,random 
    import subprocess 
    import shutil 
    import platform 
      
     
     
     
    output_file = os.path.join(os.path.dirname(os.path.realpath(__file__)),'proxy.txt') 
    global_log = 'http_proxy' + datetime.now().strftime('%Y-%m-%d') + '.log' 
    if not os.path.exists(os.path.join(os.path.dirname(os.path.realpath(__file__)),'logs')): 
      os.mkdir(os.path.join(os.path.dirname(os.path.realpath(__file__)),'logs')) 
    global_log = os.path.join(os.path.dirname(os.path.realpath(__file__)),'logs',global_log) 
     
    logging.basicConfig(level=logging.DEBUG,format='[%(asctime)s] [%(levelname)s] [%(module)s] [%(funcName)s] [%(lineno)d] %(message)s',filename=global_log,filemode='a') 
    log = logging.getLogger(__name__)  
    #manager = Manager() 
    #PROXY_LIST = manager.list() 
    mutex = threading.Lock() 
    PROXY_LIST = [] 
     
     
    def isWindows(): 
      if "Windows" in str(platform.uname()): 
      return True 
      else: 
      return False 
     
     
    def getTagsByAttrs(tagName,pageContent,attrName,attrRegValue): 
      soup = BeautifulSoup(pageContent)                                                 
      return soup.find_all(tagName, { attrName : re.compile(attrRegValue) }) 
     
     
    def getTagsByAttrsExt(tagName,filename,attrName,attrRegValue): 
      if os.path.isfile(filename): 
      f = open(filename,'r')    
      soup = BeautifulSoup(f) 
      f.close() 
      return soup.find_all(tagName, { attrName : re.compile(attrRegValue) }) 
      else: 
      return None 
     
     
    class Site1Thread(threading.Thread): 
      def __init__(self,outputFilePath): 
        threading.Thread.__init__(self) 
      self.outputFilePath = outputFilePath 
      self.fileName = str(random.randint(100,1000)) + ".html" 
      self.setName('Site1Thread') 
      
      def run(self): 
      site1_file = os.path.join(os.path.dirname(os.path.realpath(__file__)),'site.js') 
      site2_file = os.path.join(self.outputFilePath,'site.js') 
      if not os.path.isfile(site2_file) and os.path.isfile(site1_file): 
        shutil.copy(site1_file,site2_file) 
      #proc = subprocess.Popen(["bash","-c", "cd %s && ./casperjs site.js --url=http://spys.ru/free-proxy-list/IE/ --outputfile=%s" % (self.outputFilePath,self.fileName) ],stdout=subprocess.PIPE) 
      if isWindows(): 
        proc = subprocess.Popen(["cmd","/c", "%s/casperjs site.js --url=http://spys.ru/free-proxy-list/IE/ --outputfile=%s" % (self.outputFilePath,self.fileName) ],stdout=subprocess.PIPE) 
      else: 
        proc = subprocess.Popen(["bash","-c", "cd %s && ./casperjs site.js --url=http://spys.ru/free-proxy-list/IE/ --outputfile=%s" % (self.outputFilePath,self.fileName) ],stdout=subprocess.PIPE) 
      out=proc.communicate()[0] 
      htmlFileName = '' 
      #因为输出路径在windows不确定,所以这里加了所有可能的路径判断 
      if os.path.isfile(self.fileName): 
        htmlFileName = self.fileName 
      elif os.path.isfile(os.path.join(self.outputFilePath,self.fileName)): 
        htmlFileName = os.path.join(self.outputFilePath,self.fileName) 
      elif os.path.isfile(os.path.join(os.path.dirname(os.path.realpath(__file__)),self.fileName)): 
        htmlFileName = os.path.join(os.path.dirname(os.path.realpath(__file__)),self.fileName)  
      if (not os.path.isfile(htmlFileName)): 
        print 'Failed to get html content from http://spys.ru/free-proxy-list/IE/' 
        print out 
        sys.exit(3)  
      mutex.acquire() 
      PROXYList= getTagsByAttrsExt('font',htmlFileName,'class','spy14$') 
      for proxy in PROXYList: 
        tdContent = proxy.renderContents() 
        lineElems = re.split('[<>]',tdContent) 
        if re.compile(r'\d+').search(lineElems[-1]) and re.compile('(\d+\.\d+\.\d+)').search(lineElems[0]): 
        print lineElems[0],lineElems[-1] 
        PROXY_LIST.append("%s:%s" % (lineElems[0],lineElems[-1])) 
      mutex.release() 
      try: 
        if os.path.isfile(htmlFileName): 
        os.remove(htmlFileName) 
      except: 
        pass 
     
    if __name__ == '__main__': 
      try: 
      if(len(sys.argv)) < 2: 
        print "Usage:%s [casperjs path]" % (sys.argv[0]) 
        sys.exit(1)  
      if not os.path.exists(sys.argv[1]): 
        print "casperjs path: %s does not exist!" % (sys.argv[1]) 
        sys.exit(2)  
      if os.path.isfile(output_file): 
        f = open(output_file) 
        lines = f.readlines() 
        f.close 
        for line in lines: 
        PROXY_LIST.append(line.strip()) 
      thread1 = Site1Thread(sys.argv[1]) 
      thread1.start() 
      thread1.join() 
       
      f = open(output_file,'w') 
      for proxy in set(PROXY_LIST): 
        f.write(proxy+"\n") 
      f.close() 
      print "Done!" 
      except SystemExit: 
      pass 
      except: 
        errMsg = traceback.format_exc() 
        print errMsg 
        log.error(errMsg)
Python 相关文章推荐
Python中的魔法方法深入理解
Jul 09 Python
Python中使用HTMLParser解析html实例
Feb 08 Python
浅谈pandas筛选出表中满足另一个表所有条件的数据方法
Feb 08 Python
20行python代码的入门级小游戏的详解
May 05 Python
python and or用法详解
Jun 26 Python
简单了解python 邮件模块的使用方法
Jul 24 Python
通过实例解析python描述符原理作用
Jan 22 Python
python实现人机五子棋
Mar 25 Python
python为什么要安装到c盘
Jul 20 Python
Python使用socket模块实现简单tcp通信
Aug 18 Python
python获取本周、上周、本月、上月及本季的时间代码实例
Sep 08 Python
python接口自动化框架实战
Dec 23 Python
举例讲解Python程序与系统shell交互的方式
Apr 09 #Python
使用Python中的cookielib模拟登录网站
Apr 09 #Python
列举Python中吸引人的一些特性
Apr 09 #Python
Python的Bottle框架的一些使用技巧介绍
Apr 08 #Python
在Python的框架中为MySQL实现restful接口的教程
Apr 08 #Python
简单介绍Python的轻便web框架Bottle
Apr 08 #Python
常见的在Python中实现单例模式的三种方法
Apr 08 #Python
You might like
php防止sql注入示例分析和几种常见攻击正则表达式
2014/01/12 PHP
微信营销平台系统?刮刮乐的开发
2014/06/10 PHP
ThinkPHP模版引擎之变量输出详解
2014/12/05 PHP
通过chrome浏览器控制台(Console)进行PHP Debug的方法
2016/10/19 PHP
PHP工厂模式简单实现方法示例
2018/05/23 PHP
javascript操作cookie的文章(设置,删除cookies)
2010/04/01 Javascript
JS保留小数点(四舍五入、四舍六入)实现思路及实例
2013/04/25 Javascript
解析js中获得父窗口链接getParent方法以及各种打开窗口的方法
2013/06/19 Javascript
Node.js(安装,启动,测试)
2014/06/09 Javascript
HTML,CSS,JavaScript速查表推荐
2014/12/02 Javascript
nodejs中的fiber(纤程)库详解
2015/03/24 NodeJs
jQuery插件bxSlider实现响应式焦点图
2015/04/12 Javascript
JavaScript+html5 canvas绘制的圆弧荡秋千效果完整实例
2016/01/26 Javascript
从零开始学习Node.js系列教程之基于connect和express框架的多页面实现数学运算示例
2017/04/13 Javascript
jQuery 实现图片的依次加载图片功能
2017/07/06 jQuery
jsTree事件和交互以及插件plugins详解
2017/08/29 Javascript
详解PHP后期静态绑定分析与应用
2018/03/21 Javascript
vue-cli3.0配置及使用注意事项详解
2018/09/05 Javascript
vue-cli3全面配置详解
2018/11/14 Javascript
浅谈Fetch 数据交互方式
2018/12/20 Javascript
jquery-ui 进度条功能示例【测试可用】
2019/07/25 jQuery
js实现筛选功能
2020/11/24 Javascript
[04:10]2016国际邀请赛中国区预选赛第二日TOP10精彩集锦
2016/06/28 DOTA
关于python pyqt5安装失败问题的解决方法
2017/08/08 Python
python 实现将字典dict、列表list中的中文正常显示方法
2018/07/06 Python
tensorflow实现图像的裁剪和填充方法
2018/07/27 Python
基于jupyter代码无法在pycharm中运行的解决方法
2020/04/21 Python
html5的新增的标签和废除的标签简要概述
2013/02/20 HTML / CSS
三陽商会官方网站:Sanyo iStore
2019/05/15 全球购物
华为消费者德国官方网站:HUAWEI德国
2020/11/03 全球购物
关于Java finally的面试题
2016/04/27 面试题
六年级数学教学反思
2014/02/03 职场文书
会计电算化学生个人的自我评价
2014/02/08 职场文书
家庭财产分割协议范文
2014/11/24 职场文书
党组织结对共建协议书
2016/03/23 职场文书
职场中的你,辞职信写对了吗?
2019/06/26 职场文书