在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 相关文章推荐
操作Windows注册表的简单的Python程序制作教程
Apr 07 Python
python 换位密码算法的实例详解
Jul 19 Python
python入门教程 python入门神图一张
Mar 05 Python
下载python中Crypto库报错:ModuleNotFoundError: No module named ‘Crypto’的解决
Apr 23 Python
Python实现读取txt文件并转换为excel的方法示例
May 17 Python
python获取代码运行时间的实例代码
Jun 11 Python
Python实现朴素贝叶斯分类器的方法详解
Jul 04 Python
django框架forms组件用法实例详解
Dec 10 Python
pytorch常见的Tensor类型详解
Jan 15 Python
Python API len函数操作过程解析
Mar 05 Python
pyinstaller将含有多个py文件的python程序做成exe
Apr 29 Python
Python基础之元组与文件知识总结
May 19 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判断服务器是否支持Gzip压缩功能
2013/09/24 PHP
php查询whois信息的方法
2015/06/08 PHP
浅谈PHP错误类型及屏蔽方法
2017/05/27 PHP
JavaScript实现页面滚动图片加载(仿lazyload效果)
2011/07/22 Javascript
同一页面多个商品倒计时JS 基于面向对象的javascript
2012/02/16 Javascript
JS Date函数整理方便使用
2013/10/23 Javascript
js document.write()使用介绍
2014/02/21 Javascript
用于deeplink的js方法(判断手机是否安装app)
2014/04/02 Javascript
JavaScript继承基础讲解(原型链、借用构造函数、混合模式、原型式继承、寄生式继承、寄生组合式继承)
2014/08/16 Javascript
使用jQuery简单实现模拟浏览器搜索功能
2014/12/21 Javascript
jQuery学习笔记之jQuery+CSS3的浏览器兼容性
2015/01/19 Javascript
javascript中hasOwnProperty() 方法使用指南
2015/03/09 Javascript
jQuery实现带有上下控制按钮的简单多行滚屏效果代码
2015/09/04 Javascript
input点击后placeholder中的提示消息消失
2016/01/15 Javascript
原生Javascript插件开发实践
2017/01/09 Javascript
Vue2.0基于vue-cli+webpack同级组件之间的通信教程(推荐)
2017/09/14 Javascript
layui form表单提交之后重新加载数据表格的方法
2019/09/11 Javascript
JS+HTML实现自定义上传图片按钮并显示图片功能的方法分析
2020/02/12 Javascript
Python functools模块学习总结
2015/05/09 Python
在Mac OS系统上安装Python的Pillow库的教程
2015/11/20 Python
解决Python中字符串和数字拼接报错的方法
2016/10/23 Python
Pycharm2017版本设置启动时默认自动打开项目的方法
2018/10/29 Python
利用Python校准本地时间的方法教程
2019/10/31 Python
python获取栅格点和面值的实现
2020/03/10 Python
Prometheus开发中间件Exporter过程详解
2020/11/30 Python
医生实习工作总结的自我评价
2013/09/27 职场文书
策划助理岗位职责
2013/11/18 职场文书
个人授权委托书范本
2014/04/03 职场文书
幼儿园大班区域活动总结
2014/07/09 职场文书
搞笑的爱情检讨书
2014/10/01 职场文书
委托书的样本
2015/01/28 职场文书
小学家长意见怎么写
2015/06/03 职场文书
Django如何与Ajax交互
2021/04/29 Python
对Golang中的FORM相关字段理解
2021/05/02 Golang
利用python进行数据加载
2021/06/20 Python
postgres之jsonb属性的使用操作
2021/06/23 PostgreSQL