Python Selenium的js扩展实现

简介:
python写的数据采集,对一般有规律的页面用 urllib2 + BeautifulSoup + 正则就可以搞定。 但是有些页面的内容是通过js生成,或者通过js跳转的,甚至js中还加入几道混淆机制;对这种涉及页面脚本解析的内容,前面的方式便很无力。
  这时我们需要能解析、运行js的引擎——浏览器,而python selenium能提供程序与浏览器的交互接口,再加上phantomjs这个可以后台运行的浏览器,即使用 selenium + phantomjs 便可以解决以上的问题。
  selenium可以操作页面的元素,并且提供执行js脚本的接口。但其调用js脚本后并不能直接返回执行的结果,这样再采集内容的过程中就会受到一些限制。 比如我们想使用页面中的函数进行数据转换,或者获取iframe里的内容,这些js产生数据要传回比较麻烦。
  所以我便写一个简化js数据回传的扩展 exescript.py
#!/usr/bin/env python
# -*- coding:utf-8 -*-
#
# created by heqingpan
_init_js="""
(function (){
if (window.__e)
{ return;
}
var e=document.createElement('div');
e.setAttribute("id","__s_msg");
e.style.display="none";
document.body.appendChild(e);
window.__e=e;
})();
window.__s_set_msg=function(a){
window.__e.setAttribute("msg",a.toString()||"");
}
"""
_loadJsFmt="""
var script = document.createElement('script');
script.src = "{0}";
document.body.appendChild(script);
"""
_jquery_cdn="http://lib.sinaapp.com/js/jquery/1.7.2/jquery.min.js"
_warpjsfmt="__s_set_msg({0})"
class ExeJs(object):
def __init__(self,driver,trytimes=10):
from time import sleep
self.driver=driver
driver.execute_script(_init_js)
while trytimes >0:
try:
self.msgNode=driver.find_element_by_id('__s_msg')
break
except Exception:
sleep(1)
trytimes -= 1
if self.msgNode is None:
raise Exception()
def exeWrap(self,jsstr):
""" jsstr 执行后有返回值,返回值通过self.getMsg()获取 """
self.driver.execute_script(_warpjsfmt.format(jsstr))
def loadJs(self,path):
self.execute(_loadJsFmt.format(path))
def loadJquery(self,path=_jquery_cdn):
self.loadJs(path)
def execute(self,jsstr):
self.driver.execute_script(jsstr)
def getMsg(self):
return self.msgNode.get_attribute('msg')
打开ipython上一个例子,获取博客园首页文章title列表
from selenium import webdriver
import exescript
d=webdriver.PhantomJS("phantomjs")
d.get("http://www.cnblogs.com/")
exejs=exescript.ExeJs(d)
exejs.exeWrap('$(".post_item").length')
print exejs.getMsg()
#out:
"""
20
"""
jsstr="""(function(){
var r=[];
$(".post_item").each(function(){
var $this=$(this);
var $h3=$this.find("h3");
r.push($h3.text());
});
return r.join(',');})()"""
exejs.exeWrap(jsstr)
l=exejs.getMsg()
for title in l.split(','):
print title
#out:
"""
mac TeamTalk开发点点滴滴之一——DDLogic框架分解上
The directfb backend was supported together with linux-fb backend in GTK+2.10
Science上发表的超赞聚类算法
功能齐全、效率一流的免费开源数据库导入导出工具(c#开发,支持SQL server、SQLite、ACCESS三种数据  库),每月借此处理数据5G以上
企业级应用框架(三)三层架构之数据访问层的改进以及测试DOM的发布
Unity3D 第一季 00 深入理解U3D开发平台
Welcome to Swift (苹果官方Swift文档初译与注解二十一)---140~147页(第三章--集合类型)
appium简明教程(11)——使用resource id定位
SQL语句汇总(终篇)—— 表联接与联接查询
fopen警告处理方式
AndroidWear开发之HelloWorld篇
AMD and CMD are dead之KMD.js版本0.0.2发布
SQL语句汇总(三)——聚合函数、分组、子查询及组合查询
DevExpress GridControl功能总结
ASP.NET之Jquery入门级别
2014年前端面试经历
grunt源码解析:整体运行机制&grunt-cli源码解析
跟用户沟通,问题尽量分析清楚,以及解决问题
ASP.NET之Ajax系列(一)
算法复杂度分析
"""

最新内容请见作者的GitHub页:http://qaseven.github.io/
相关文章
|
1月前
|
JSON JavaScript 前端开发
在Python中调用和执行JavaScript
在Python中调用和执行JavaScript主要通过`PyExecJS`库实现。安装库后,可以使用`execjs.compile`编译JS代码并用`eval`或`call`执行。此外,还能加载JavaScript库和框架,调用外部JS文件,处理返回值,以及在两者间传递数据。Python和JavaScript各有优劣,适用于不同场景,结合使用可增强项目功能和灵活性。
27 0
|
2月前
|
JavaScript 前端开发 测试技术
Python Selenium基本用法
Python Selenium基本用法
33 2
|
2月前
|
存储 JavaScript 前端开发
在JavaScript中,对象和数组是如何进行扩展的?
在JavaScript中,对象和数组是如何进行扩展的?
22 4
|
3月前
|
前端开发 关系型数据库 MySQL
基于python+django+vue.js开发的社区养老管理系统
基于python+django+vue.js开发的社区养老管理系统
117 1
|
2天前
|
XML 前端开发 JavaScript
javascript扩展小知识(必须细节)
javascript扩展小知识(必须细节)
|
16天前
|
前端开发 测试技术 C++
Python自动化测试面试:unittest、pytest与Selenium详解
【4月更文挑战第19天】本文聚焦Python自动化测试面试,重点讨论unittest、pytest和Selenium三大框架。unittest涉及断言、TestSuite和覆盖率报告;易错点包括测试代码冗余和异常处理。pytest涵盖fixtures、参数化测试和插件系统,要注意避免过度依赖unittest特性。Selenium的核心是WebDriver操作、等待策略和测试报告生成,强调智能等待和元素定位策略。掌握这些关键点将有助于提升面试表现。
23 0
|
25天前
|
Web App开发 测试技术 网络安全
|
28天前
|
JavaScript 前端开发 API
如何利用Python的Flask框架与Vue.js创建RESTful API服务
【4月更文挑战第10天】本文介绍了如何使用Flask和Vue.js创建一个前后端分离的RESTful API服务。Flask作为后端框架,负责提供CRUD操作,与SQLite数据库交互;Vue.js作为前端框架,构建用户界面并利用axios库与后端API通信。通过示例代码,展示了Flask设置路由处理用户数据以及Vue组件如何调用API获取和操作数据。此基础结构为构建更复杂的Web应用提供了起点。
|
2月前
|
JavaScript
js开发:请解释什么是ES6的扩展运算符(spread operator),并给出一个示例。
ES6的扩展运算符(...)用于可迭代对象展开,如数组和对象。在数组中,它能将一个数组的元素合并到另一个数组。例如:`[1, 2, 3, 4, 5]`。在对象中,它用于复制并合并属性,如`{a: 1, b: 2, c: 3}`。
13 3
|
2月前
|
Web App开发 前端开发 JavaScript
Python Selenium是一个强大的自动化测试工具
Python Selenium是一个强大的自动化测试工具