在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 简易计算器程序,代码就几行
Aug 29 Python
使用python绘制人人网好友关系图示例
Apr 01 Python
PyQt 线程类 QThread使用详解
Jul 16 Python
python音频处理用到的操作的示例代码
Oct 27 Python
Tensorflow 自带可视化Tensorboard使用方法(附项目代码)
Feb 10 Python
浅析Python 实现一个自动化翻译和替换的工具
Apr 14 Python
python cumsum函数的具体使用
Jul 29 Python
Golang GBK转UTF-8的例子
Aug 26 Python
python计算导数并绘图的实例
Feb 29 Python
python 图像判断,清晰度(明暗),彩色与黑白实例
Jun 04 Python
python字符串的index和find的区别详解
Jun 20 Python
详解Anaconda安装tensorflow报错问题解决方法
Nov 01 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 数组遍历的差异(array_diff 的实现)
2008/03/23 PHP
PHP下用rmdir实现删除目录的三种方法小结
2008/04/20 PHP
PHP小技巧之函数重载
2014/06/02 PHP
PHP微框架Dispatch简介
2014/06/12 PHP
PHP JSON出错:Cannot use object of type stdClass as array解决方法
2014/08/16 PHP
php简单socket服务器客户端代码实例
2015/05/18 PHP
PHP书写格式详解(必看)
2016/05/23 PHP
页面只有一个text的时候,回车自动submit的解决方法
2010/08/12 Javascript
js 判断一个元素是否在页面中存在
2012/12/27 Javascript
js Select下拉列表框进行多选、移除、交换内容的具体实现方法
2013/08/13 Javascript
js中for in的用法示例解析
2013/12/25 Javascript
javascript数字时钟示例分享
2014/04/23 Javascript
JQuery球队选择实例
2015/05/18 Javascript
基于jQuery实现的双11天猫拆红包抽奖效果
2015/12/01 Javascript
Vue cli+mui 区域滚动的实例代码
2018/01/25 Javascript
React中阻止事件冒泡的问题详析
2019/04/12 Javascript
Vue 使用formData方式向后台发送数据的实现
2019/04/14 Javascript
pm2发布node配置文件ecosystem.json详解
2019/05/15 Javascript
详解vue 组件
2020/06/11 Javascript
[01:02:48]2018DOTA2亚洲邀请赛小组赛 A组加赛 Newbee vs Liquid
2018/04/03 DOTA
python实现生命游戏的示例代码(Game of Life)
2018/01/24 Python
python将txt文件读取为字典的示例
2018/12/22 Python
django admin 添加自定义链接方式
2020/03/11 Python
解决Jupyter Notebook使用parser.parse_args出现错误问题
2020/04/20 Python
Python flask框架实现浏览器点击自定义跳转页面
2020/06/04 Python
番木瓜健康和保健产品第一大制造商:Herbal Papaya
2017/04/25 全球购物
Senreve官网:美国旧金山的奢侈手袋品牌
2019/03/21 全球购物
.NET里面什么时候需要调用垃圾回收
2015/06/01 面试题
三年大学生活自我鉴定
2014/01/21 职场文书
个人租房协议书
2014/04/09 职场文书
卫校毕业生个人自我鉴定
2014/04/28 职场文书
团队队名口号大全
2014/06/06 职场文书
小学综治宣传月活动总结
2014/07/02 职场文书
2015年教师节主持词
2015/07/03 职场文书
人力资源部工作计划
2019/05/14 职场文书
广告文案的撰写技巧(实用干货)
2019/08/23 职场文书