在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 相关文章推荐
Hadoop中的Python框架的使用指南
Apr 22 Python
在Python程序中操作文件之isatty()方法的使用教程
May 24 Python
Python基于sftp及rsa密匙实现远程拷贝文件的方法
Sep 21 Python
Python实现批量读取图片并存入mongodb数据库的方法示例
Apr 02 Python
替换python字典中的key值方法
Jul 06 Python
django之跨表查询及添加记录的示例代码
Oct 16 Python
Python 读取WAV音频文件 画频谱的实例
Mar 14 Python
Pytorch实现将模型的所有参数的梯度清0
Jun 24 Python
python设置中文界面实例方法
Oct 27 Python
Numpy中的数组搜索中np.where方法详细介绍
Jan 08 Python
python如何进行基准测试
Apr 26 Python
python3 hdf5文件 遍历代码
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
10个实用的PHP代码片段
2011/09/02 PHP
PHP反转字符串函数strrev()函数的用法
2012/02/04 PHP
记录mysql性能查询过程的使用方法
2013/05/02 PHP
Laravel执行migrate命令提示:No such file or directory的解决方法
2016/03/16 PHP
Joomla框架实现字符串截取的方法示例
2017/07/18 PHP
event.srcElement+表格应用
2006/08/29 Javascript
解析jQuery与其它js(Prototype)库兼容共存
2013/07/04 Javascript
JS保留两位小数 四舍五入函数的小例子
2013/11/20 Javascript
纯javascript实现四方向文本无缝滚动效果
2015/06/16 Javascript
javascript 内置对象及常见API详细介绍
2016/11/01 Javascript
jQuery实现链接的title快速出现的方法
2017/02/20 Javascript
12个非常有用的JavaScript技巧
2017/05/17 Javascript
在小程序/mpvue中使用flyio发起网络请求的方法
2018/09/13 Javascript
推荐下python/ironpython:从入门到精通
2007/10/02 Python
Python3安装Scrapy的方法步骤
2017/11/23 Python
python 实现将多条曲线画在一幅图上的方法
2019/07/07 Python
Python使用scipy模块实现一维卷积运算示例
2019/09/05 Python
DataFrame.to_excel多次写入不同Sheet的实例
2019/12/02 Python
在django中自定义字段Field详解
2019/12/03 Python
利用PyCharm操作Github(仓库新建、更新,代码回滚)
2019/12/18 Python
Python用类实现扑克牌发牌的示例代码
2020/06/01 Python
如何在vscode中安装python库的方法步骤
2021/01/06 Python
使用Python webdriver图书馆抢座自动预约的正确方法
2021/03/04 Python
css3 column实现卡片瀑布流布局的示例代码
2018/06/22 HTML / CSS
电子商务专业个人的自我评价
2013/12/19 职场文书
机械设计职业生涯规划书
2013/12/27 职场文书
销售业务员岗位职责
2014/01/29 职场文书
医药销售自我评价200字
2014/09/11 职场文书
工会2014法制宣传日活动总结
2014/11/01 职场文书
教师师德工作总结2015
2015/07/22 职场文书
2016年国庆节新闻稿范文
2015/11/25 职场文书
中学音乐课教学反思
2016/02/18 职场文书
2016年百日安全生产活动总结
2016/04/06 职场文书
用Python简陋模拟n阶魔方
2021/04/17 Python
Spring Cloud Gateway去掉url前缀
2021/07/15 Java/Android
源码安装apache脚本部署过程详解
2022/09/23 Servers