在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定时执行指定函数的方法
May 27 Python
Python实现excel转sqlite的方法
Jul 17 Python
Python scikit-learn 做线性回归的示例代码
Nov 01 Python
python merge、concat合并数据集的实例讲解
Apr 12 Python
Python使用pylab库实现绘制直方图功能示例
Jun 01 Python
python tornado微信开发入门代码
Aug 24 Python
在python中,使用scatter绘制散点图的实例
Jul 03 Python
python使用Qt界面以及逻辑实现方法
Jul 10 Python
如何理解python对象
Jun 21 Python
如何从csv文件构建Tensorflow的数据集
Sep 21 Python
如何使用Python进行PDF图片识别OCR
Jan 22 Python
python实现图片九宫格分割的示例
Apr 25 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
mysql时区问题
2008/03/26 PHP
PHP 身份证号验证函数
2009/05/07 PHP
php 分页类 扩展代码
2009/06/11 PHP
使用php+apc实现上传进度条且在IE7下不显示的问题解决方法
2013/04/25 PHP
php实现的递归提成方案实例
2015/11/14 PHP
一个简单的javascript类定义例子
2009/09/12 Javascript
判断window.onload是否多次使用的方法
2014/09/21 Javascript
js实现鼠标划过给div加透明度的方法
2015/05/25 Javascript
基于javascript实现动态显示当前系统时间
2016/01/28 Javascript
JS回调函数简单用法示例
2017/02/09 Javascript
EasyUI的TreeGrid的过滤功能的解决思路
2017/08/08 Javascript
微信小程序使用navigateTo数据传递的实例
2017/09/26 Javascript
JavaScript函数式编程(Functional Programming)声明式与命令式实例分析
2019/05/21 Javascript
vue 使用rules对表单字段进行校验的步骤
2020/12/25 Vue.js
netbeans7安装python插件的方法图解
2013/12/24 Python
Android分包MultiDex策略详解
2017/10/30 Python
Django中Model的使用方法教程
2018/03/07 Python
Linux 修改Python命令的方法示例
2018/12/03 Python
对Python3+gdal 读取tiff格式数据的实例讲解
2018/12/04 Python
python计算阶乘和的方法(1!+2!+3!+...+n!)
2019/02/01 Python
numpy.where() 用法详解
2019/05/27 Python
python剪切视频与合并视频的实现
2020/03/03 Python
CSS3实现多背景展示效果通过CSS3定位多张背景
2014/08/10 HTML / CSS
Shopee越南:东南亚与台湾电商平台
2019/02/03 全球购物
vue项目实现分页效果
2021/03/24 Vue.js
电信专业毕业生推荐信
2013/11/18 职场文书
自主招生自荐信范文
2013/12/04 职场文书
女大学生自我鉴定
2013/12/09 职场文书
服装设计专业自荐书范文
2013/12/30 职场文书
求职信怎么写
2014/05/23 职场文书
寝室长工作失责检讨书
2014/10/06 职场文书
奥巴马开学演讲观后感
2015/06/12 职场文书
员工离职证明范本
2015/06/12 职场文书
python通配符之glob模块的使用详解
2021/04/24 Python
go:垃圾回收GC触发条件详解
2021/04/24 Golang
AudioContext 实现音频可视化(web技术分享)
2022/02/24 Javascript