在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代码检查工具pylint 让你的python更规范
Sep 05 Python
Python中使用装饰器时需要注意的一些问题
May 11 Python
Python实现输出程序执行进度百分比的方法
Sep 16 Python
Python实现动态图解析、合成与倒放
Jan 18 Python
Python中协程用法代码详解
Feb 10 Python
Python-OpenCV基本操作方法详解
Apr 02 Python
flask框架中勾子函数的使用详解
Aug 01 Python
python覆盖写入,追加写入的实例
Jun 26 Python
Python文字截图识别OCR工具实例解析
Mar 05 Python
基于Python第三方插件实现西游记章节标注汉语拼音的方法
May 22 Python
python 爬取英雄联盟皮肤并下载的示例
Dec 04 Python
Python捕获、播放和保存摄像头视频并提高视频清晰度和对比度
Apr 14 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
抓取YAHOO股票报价的类
2009/05/15 PHP
php 搜索框提示(自动完成)实例代码
2012/02/05 PHP
保存到桌面、设为桌面且带图标的PHP代码
2013/11/19 PHP
phpmailer发送邮件之后,返回收件人是否阅读了邮件的方法
2014/07/19 PHP
PHP上传图片、删除图片简单实例
2016/11/12 PHP
PHP如何搭建百度Ueditor富文本编辑器
2018/09/21 PHP
浅谈PHP匿名函数和闭包
2019/03/08 PHP
jquery属性过滤选择器使用示例
2013/06/18 Javascript
jQuery插件pagination实现分页特效
2015/04/12 Javascript
jquery仿百度百科底部浮动导航特效
2015/08/08 Javascript
JavaScript实现网页加载进度条代码超简单
2015/09/21 Javascript
又一款MVVM组件 构建自己的Vue组件(2)
2017/03/13 Javascript
WebSocket实现简单客服聊天系统
2017/05/12 Javascript
promise处理多个相互依赖的异步请求(实例讲解)
2017/08/03 Javascript
深入理解requireJS-实现一个简单的模块加载器
2018/01/15 Javascript
nodejs图片处理工具gm用法小结
2018/12/12 NodeJs
JS查找孩子节点简单示例
2019/07/25 Javascript
vue实现下拉加载其实没那么复杂
2019/08/13 Javascript
Node.js 中判断一个文件是否存在
2020/08/24 Javascript
[54:51]Ti4 冒泡赛第二轮LGD vs C9 3
2014/07/14 DOTA
python通过imaplib模块读取gmail里邮件的方法
2015/05/08 Python
Python内置模块hashlib、hmac与uuid用法分析
2018/02/12 Python
python pandas dataframe 按列或者按行合并的方法
2018/04/12 Python
Matplotlib scatter绘制散点图的方法实现
2020/01/02 Python
python把一个字符串切开的实例方法
2020/09/27 Python
前端制作动画的几种方式(css3,js)
2016/12/12 HTML / CSS
H5仿微信界面教程(一)
2017/07/05 HTML / CSS
公司营业员的自我评价
2014/03/04 职场文书
班委竞选演讲稿
2014/04/28 职场文书
岗位标兵事迹材料
2014/05/17 职场文书
天地会口号
2014/06/17 职场文书
教师四风问题整改措施
2014/09/25 职场文书
师德师风自我剖析材料
2014/09/27 职场文书
领导欢迎词致辞
2015/01/23 职场文书
2015年小学二年级班主任工作总结
2015/05/21 职场文书
介绍信应该怎么开?
2019/04/03 职场文书