使用python简单封装selenium常用函数

使用python简单封装selenium常用函数,第1张

年前走查脚本代码时,发现大家对selenium功能都在重复造轮子,而且容易出现一些常见低级bug。于是在闲暇之余,封装一些常用的selenium功能。

在某些网页中,存在多个frame嵌套。而selenium提供的find_element函数只能在当前frame中查找,不能切换到其他frame中,需要从最上级frame中逐步切换(当然也可以指定xpath的绝对路径,但是一般没人这么做)。在我们写代码过程中,需要明确知道当前frame位置和需要寻找元素的frame位置。在frame切换过程中,容易因为疏忽导致frame切换错误导致元素无法找到的bug。

页面中分布的frame,可以理解为树状结构。因此我们可以采用递归的方式, 沿着某条搜索路线frame节点,依次对树中每个节点均做一次访问。

我们以163网址上的登录框为例:点击登录按钮,d出登录iframe页面。输入框位置在iframe中,因此我们不能使用xpath获取元素位置,需要进入iframe中,然后获取元素。

手动切换ifame可能会产生bug,因此需要一套自动切换和检索frame的机制。具体代码如下:

需要注意的是:如果页面中多个frame中,存在相同的xpath元素。还是需要指定frame的路径,否则会返回搜索到的第一个元素。

强制等待

直接调用系统timesleep函数,不管页面加载情况一定会等待指定的时间, 即使元素已被加载 。

1如果设置的时间较长,会浪费时间

2如果设置的时间较短,元素可能没有加载。

页面中某元素如果未能立即加载,隐式等待告诉WebDriver需等待一定的时间,然后去查找元素。默认不等待,隐式等待作用于整个WebDriver周期,只需设置一次即可。

1在上文的find_element函数中,采用递归方式在所有frame寻找元素。若采用隐式等待,则在每个frame中都需要等待设定的时间,耗时非常长。

2某些页面我们想要的元素已经加载完毕,但是部分其他资源未加载。隐式等待必须等待所有元素加载完毕,增加额外等待时间。

显示等待一般作用于某一个元素,在设定的时间范围内,默认每间隔05秒查找元素。返回被加载的元素,若超过设定的时间范围未能查找则报错。显示等待作为selenium常用的等待机制,我们来看下他的源码和机制。

driver 注释中解释为WebDriver实例,但是代码中并未有相关检测,因此可以传入任何对象

但是__repr__函数中使用到session_id属性,如果需要显示属性或者转为str对象,最好在driver对象中添加session_id属性

在until函数中,我们可以看到driver对象传入method函数。在计时结束前,在不断循环执行method函数,如果method函数有正常返回值则退出循环,否则报TimeoutException错误。

可以采用装饰器对隐式等待进行封装,这样代码更加精简

同样的,采用装饰器对其他常用的函数进行封装,例如强制等待、点击、输入文本等。

装饰器虽然很方便,但也会产生一些麻烦。例如在find_element函数递归调用过程中,理应只要执行一次装饰器函数。但因为装饰器已经装饰完毕,导致每次递归都会执行。例如强制等待的sleep函数,如果递归次数越多等待时间越长。

解除装饰器一般有两种做法:一是约定参数,当递归第二次调用时则不生效。例如

这种方式实现简单,容易理解。但是增加了参数限制,在fun函数中就不能使用first_sleep参数。

二是采用装饰器采用wrapped实现,通过访问wrapped属性获得原始函数。例如

但是某一个函数被多个装饰器装饰时,需要递归解除装饰器。例如

最后整体代码如下

这次的封装其实还存在很多问题

1find_element函数不仅仅只是提供查找元素功能,还提供一些其他功能,因此叫element_operation更为合适。

2find_element函数的参数过多,并且很多参数的使用并不在函数本身中,对代码阅读很不友好。

3得小心避免参数重复问题,假设装饰器sleep和装饰器wait_time都使用time这个参数,将无法区分具体是哪个函数使用。

4不利于扩展和维护,当功能过多时find_element的参数过于庞大。

如果只是简单地封装和使用,上面这种方式也能达到较好的效果。如果想进一步封装,建议采用链式调用方式,装饰器辅助封装。例如

这样函数的扩展性和可阅读性有较大的提升

#include <iostream>

#include <vector>

#include <list>

using namespace std;

template<typename ElementType, typename ContainerType>

ElementType maxElement(ContainerType &container)

{

typename ContainerType::iterator it = containerbegin();

ElementType max = it;

while( ++it != containerend() )

{

if( it > max )max = it;

}

return max;

}

template<typename ElementType, typename ContainerType>

ElementType minElement(ContainerType &container)

{

typename ContainerType::iterator it = containerbegin();

ElementType min = it;

while( ++it != containerend() )

{

if( it < min )min = it;

}

return min;

}

int main(int argc, char argv[])

{

vector<int> lst;

lstpush_back(1);

lstpush_back(5);

lstpush_back(3);

int max = maxElement<int, vector<int> >(lst);

printf("max is %d\n", max);

int min = minElement<int, vector<int> >(lst);

printf("min is %d\n", min);

list<int> lst2;

lst2push_back(10);

lst2push_back(50);

lst2push_back(30);

max = maxElement<int, list<int> >(lst2);

printf("max is %d\n", max);

min = minElement<int, list<int> >(lst2);

printf("min is %d\n", min);

return 0;

}

//1

int ReadRealData(double dArray[], int nCount)

{

    long sumData = 0;

    double dData;

    int m_nCount;

    cout<<"请输入数组的个数:"<<endl;

    cin>>m_nCount;

    while(m_nCount<=nCount)

    {

        cin>>dData;

        if (dData == "\n") break;

        dArray+sumData = &dData;

        sumData = sumData + 1;

    }

    return sumData;

   

}

//2

int FindMinElement (double dArray[], int nCount)

{

    double pMin;

    pMin = dArray;

    int pos=0;

   for(int i = 0;i<nCount;i++)

   {

       if(pMin>(dArray+i))

       {

           pMin=(dArray+i);

           pos = i;

       }

   } 

   

   return pos;

}

int FindMaxElement (double dArray[], int nCount)

{

    double pMax;

    pMax = dArray;

    int pos=0;

   for(int i = 0;i<nCount;i++)

   {

       if(pMax < (dArray+i))

       {

           pMin =  (dArray+i);

           pos = i;

       }

   } 

   

   return pos;

}

double Average(double dArray[], int nCount)

{

    double dsum;

    for(int  i = 0;i<nCount;i++)

    {

        dsum = dsum +(dArray+i);

    }

    return dsum/nCount;

}

double Variance(double dArray[], int nCount)

{

    double dresult;

    //方差公式忘记了  你可以仿照上一个函数 根据公式自行写

    return dresult;

}

//测试函数自己写

1)循环

序列中的每个元素执行某项 *** 作 for_each()

2)查找 在序列中找出某个值的第一次出现的位置

find(a,a+

size,n)

返回b

当b=a+size

即没找到,a为指针

在序列中找出符合某谓词的第一个元素 find_if()

在序列中找出一子序列的最后一次出现的位置 find_end()

在序列中找出第一次出现指定值集中之值的位置 find_first_of()

在序列中找出相邻的一对值 adjacent_find()

计数 在序列中统计某个值出现的次数 count()

在序列中统计与某谓词匹配的次数 count_if()

比较 找出两个序列相异的第一个元素 mismatch()

两个序列中的对应元素都相同时为真

在序列中找到等于某值的连续n次出现的位置 equal(a,a+n,b,cmp)

equal_range(a,a+n,x)

搜索 在序列中找出一子序列的第一次出现的位置 search()

在序列中找出一值的连续n次出现的位置 search_n()

修改性序列 *** 作(27个)

复制 从序列的第一个元素起进行复制 copy()

从序列的最后一个元素起进行复制 copy_backward()

交换 交换两个元素 swap()

交换指定范围的元素 swap_ranges()

交换由迭代器所指的两个元素 iter_swap()

变换 将某 *** 作应用于指定范围的每个元素 transform()

替换 用一个给定值替换一些值 replace()

替换满足谓词的一些元素 replace_if()

复制序列时用一给定值替换元素 replace_copy()

复制序列时替换满足谓词的元素 replace_copy_if()

填充 用一给定值取代所有元素 fill()

用一给定值取代前n个元素 fill_n()

生成 用一 *** 作的结果取代所有元素 generate()

用一 *** 作的结果取代前n个元素 generate_n()

删除 删除具有给定值的元素 remove()

删除满足谓词的元素 remove_if()

复制序列时删除具有给定值的元素 remove_copy()

复制序列时删除满足谓词的元素 remove_copy_if()

唯一 删除相邻的重复元素 unique()

复制序列时删除相邻的重复元素 unique_copy()

反转 反转元素的次序 reverse(a,a+n)

复制序列时反转元素的次序 reverse_copy()

环移 循环移动元素 rotate(a,a+m,a+n)

以m位置为界交换前后序列

复制序列时循环移动元素 rotate_copy()

随机 采用均匀分布来随机移动元素 random_shuffle()

划分 将满足某谓词的元素都放到前面 partition()

将满足某谓词的元素都放到前面并维持原顺序 stable_partition()

序列排序及相关 *** 作(27个)

排序 以很好的平均效率排序 sort(a,a+20,cmp)

bool cmp( int a,

int b )

{ return a>b; }

在容器中或string用begin()

排序,并维持相同元素的原有顺序 stable_sort()

将序列的前一部分排好序 partial_sort()

复制的同时将序列的前一部分排好序 partial_sort_copy()

第n个元素 将第n各元素放到它的正确位置 nth_element()

二分检索 找到大于等于某值的第一次出现 lower_bound()

找到大于某值的第一次出现 upper_bound()

找到(在不破坏顺序的前提下)可插入给定值的最大范围 equal_range()

在有序序列中确定给定元素是否存在 binary_search()

归并 归并两个有序序列 merge()

归并两个接续的有序序列 inplace_merge()

有序结构上的集合 *** 作 一序列为另一序列的子序列时为真 includes()

构造两个集合的有序并集 set_union()

构造两个集合的有序交集 set_intersection()

构造两个集合的有序差集 set_difference()

构造两个集合的有序对称差集(并-交) set_symmetric_difference()

堆 *** 作 向堆中加入元素 push_heap()

从堆中d出元素 pop_heap()

从序列构造堆 make_heap()

给堆排序 sort_heap()

最大和最小 两个值中较小的 min()

两个值中较大的 max()

序列中的最小元素 min_element(a,a+n)

序列中的最大元素 max_element()

词典比较 两个序列按字典序的第一个在前 lexicographical_compare()

排列生成器 按字典序的下一个排列 next_permutation()

按字典序的前一个排列 prev_permutation()

子查询是SQL语句中非常重要的功能特性,它可以在SQL语句中利用另外一条SQL语句的查询结果,在Hibernate中HQL查询同样对子查询功能提供了支持。如下面代码所示:

List list=sessioncreateQuery(“from Customer c where 1>(select count(o) from corders o)”)list();

上面的程序查询订单数超过1的所有客户,因此和上面子查询HQL语句对应的SQL语句为:

Select from Customer c where 1>(select count(oid) from Order o where cid=ocustomer_ID);

如果子查询返回多条记录,则可以使用下面关键字:

all:表示子查询语句返回的所有记录

any:表示子查询语句返回的任意一条结果

some:与”any”等价

in:与”=any”等价

exists:表示子查询语句至少返回一条记录

例如:查询存在一条订单价格大于100的客户

From Customer c where 100>any(select oprice from corders o);

如果在子查询中 *** 作集合,HQL提供了一组 *** 纵集合的函数和属性:

size()函数和size属性:获得集合中元素的数量

minIndex()函数和minIndex属性:对于建立了索引的集合获得最小索引值(关于集合索引参考第一部分映射值类型集合)

minElement()函数和minElement属性:对于包含基本类型的元素集合,获得集合中值最小的元素

maxElement()函数和maxElement属性:对于包含基本类型元素的集合,获得集合中值最大的元素

element()函数:获得集合中所有元素

例如:查询订单数大于0的客户

From Customer c where size(corders)>0;或者From Customer c where corderssize>0;

以上HQL语句会生成类似如下的SQL语句:

Select from customer c where 0>(select count(oid) from order where o customer_ID =cid);

#include <iostream>

#include <vector>

#include <iterator>

#include <algorithm>

#include <mathh>

using namespace std;

typedef double DataType;

typedef vector<DataType> DataList;

DataType Average(DataList const & data_list)

{

size_t n;

DataType sum;

DataList::const_iterator ite = data_listbegin();

if ( ite == data_listend() ) return (DataType) 0;

n = data_listsize();

for (sum = ite++; ite != data_listend(); ite++)

{

sum += ite;

}

return sum / n;

}

DataType StdDev(DataList const & data_list)

{

size_t n;

DataType avg, var, diff;

DataList::const_iterator ite = data_listbegin();

if ( ite == data_listend() ) return (DataType) 0;

n = data_listsize();

avg = Average(data_list);

var = 0;

for (;ite != data_listend(); ite++)

{

diff = ite - avg;

var += diff diff;

}

return sqrt(var/n);

}

int main(int argc, char argv)

{

DataList data_list;

DataType min=0, max=0, avg=0, dev=0, ele;

while ( cingood() && cinpeek() != '\n') {

cin >> ele; data_listpush_back(ele);

}

min = min_element(data_listbegin(), data_listend());

max = max_element(data_listbegin(), data_listend());

avg = Average(data_list);

dev = StdDev(data_list);

coutprecision(4);

coutsetf(ios::fixed, ios::floatfield);

cout << "Min: " << min << endl

<< "Max: " << max << endl

<< "Average: " << avg << endl

<< "Standard deviation: " << dev << endl;

coutunsetf(ios::floatfield);

return 0;

}

这里使用了函数模板

template <class T>

T min(T list, unsigned int len)

{ return (std::min_element(list,list+len)); }

a记录数组元素 N记录个数

#include<stdioh>

int a[100], N;

intfind_min_element(intbegin, intend) {

intret=begin, p;

for(p=begin+1; p<end; ++p)

if(p<ret) ret=p;

// return the position of the min element in the range [begin,end)

return ret;

}

interase_element(intpos,intbegin,intend) {

intp=pos;

for(;p+1<end;++p)

p=(p+1);

// return the position of the end of the array

return p;

}

int output(intbegin, intend) {

int p=begin;

for(;p<end;++p)

printf("%4d", p);

printf("\n");

}

int main() {

int i;

// input the array

scanf("%d", &N);

for(i=0;i<N;++i) scanf("%d", a+i);

// work1

// find the position of the min element

intp = find_min_element(a, a+N);

printf("min element = %d\n", p);

// erase the element at position p

N=erase_element(p,a,a+N)-a;

//output the new array

printf("elment number : %d\n", N);

output(a,a+N);

// work2

p = find_min_element(a,a+N);

printf("min element = %d\n", p);

return 0;

}

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/11669163.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-17
下一篇 2023-05-17

发表评论

登录后才能评论

评论列表(0条)

保存