Selenium模拟顾客操作,搭建虚构主机步骤
分类:long8

long8 1

正文首要内容

  种类类型分类:

    (1)容器体系、扁平连串

Selenium模拟顾客操作,搭建虚构主机步骤。    (2)可变类别、不可变类别

  列表推导式

  生成器表达式

  元组拆包

  切片

  排序(list.sort方法和sorted函数)

  bisect

 

python高级——目录

  文中代码均位于github上:https://github.com/ampeeg/cnblogs/tree/master/python高级

 

功能的宏图当初的愿景:
  管理犬牙相错的xml相比较,屏蔽同节点前后相继顺序的震慑

爬虫(Spider),反爬虫(Anti-Spider),反反爬虫(Anti-Anti-Spider) 之间恢宏壮阔的斗争...

源代码是这么:

队列类型分类

 

   所谓连串,即成分有序排列,python规范库用C完成了丰裕的队列类型,遵照体系中是或不是可寄存不相同连串的数量分为"容器连串"和"扁平系列"。

  容器连串能够寄放统统类型的多少,而扁平类别只可以寄放一类别型      

    容器序列:list、tuple、collections.deque   
    扁平序列:str、bytes、bytearray、memoryview、array.array
  
  按照是否能修改的标准序列又可分为"可变序列"和"不可变序列":      
    可变序列:list、bytearrary、array.arrary、collections.deque和memoryview   
    不可变序列:tuple、str和bytes

  由于可变序列继承自不可变序列,所以可变序列继承的方法也较多,下面看看它们包含的方法:   
方法名 不可变序列 可变序列
__contains__  有 有 
__iter__  有  有 
 __len__  有  有 
__getitem__   有  有 
__reversed__   有  有 
index   有  有 
count   有  有 
__setitem__    有 
__delitem__   有 
insert   有 
append   有 
reverse   有 
extend   有 
pop   有 
remove   有 
__iadd__    有 

  

  大家以tuple和list类型为例,相比较源代码中的方法,可以明显开采list的措施多于tuple:

  

long8 2

 

重大涉嫌知识点:

  • 小莫想要某站上全部的影片,写了标准的爬虫(基于HttpClient库),不断地遍历某站的影视列表页面,根据Html 剖判电影名字存进自个儿的数据库。

  • 这些站点的运行小黎开掘有个别时刻段须要量陡增,分析日志开掘都以IP(xxx.xxx.xxx.xxx)这么些客户,并且 user-agent 照旧Python-urllib/2.7 ,基于这两点推断非人类后一向在服务器上封闭扼杀。

  • 小莫电影只爬了一半,于是也针对的改造了下战略:1. user-agent 效仿百度("Baiduspider..."),2. IP每爬半小时就换二个IP代理。

  • 小黎也发觉了相应的变迁,于是在服务器上设置了二个功效限制,每分钟超越1二十三回呼吁的再屏蔽IP。 同期思索到百度家的爬虫有十分大概率会被误伤,想想商城机构每月几八千0的投放,于是写了个本子,通过 hostname 检查下那么些 ip 是还是不是真的百度家的,对那个 ip 设置三个白名单。

  • 小莫开掘了新的范围后,想着作者也不急着要那几个数据,留给服务器慢慢爬吧,于是修改了代码,随机1-3秒爬一回,爬12回歇息10秒,每一日只在8-12,18-20点爬,隔几天还休憩一下。

  • 小黎看着新的日志头都大了,再设定法规非常的大心会有剧毒真实客户,于是计划换了八个思路,当3个钟头的总央求当先四十八次的时候弹出多个验证码弹框,未有正确输入的话就把 IP 记录进黑名单。

  • 小莫看见验证码有个别傻脸了,不过亦不是不曾章程,先去学学了图像识别(关键词 PIL,tesseract),再对验证码进行了二值化,分词,情势磨炼今后,不问可见最终识别了小黎的验证码(关于验证码,验证码的辨别,验证码的反识别也是贰个恢弘壮丽的创新优质产品史...),之后爬虫又跑了四起。

  • 小黎是个坚强的好同学,见到验证码被一锅端后,和支出同学商讨了转换下开辟情势,数据并不再直接渲染,而是由前端同学异步获取,並且经过 JavaScript 的加密库生成动态的 token,同一时间加密库再张开模糊。

  • 张冠李戴过的加密库就从未主意了么?当然不是,能够稳步调试,找到加密原理,可是小可能希图用如此耗费时间耗力的措施,他扬弃了依照HttpClient的爬虫,选取了安置浏览器引擎的爬虫(关键词:PhantomJS,Selenium),在浏览器引擎运转页面,直接获取了不利的结果,又一回获得了对方的多少。

  • 小黎:.....

Selenium

s=b'^SdVkT#S ]`Y\!^)x8fx80ism'
key=''
for i in s:
     i=ord(i)-16
     key+=chr(i^32)
print (key)

列表推导式

# 列表推导式生成的是列表,会占用系统内存
# 基本语法

list_1 = [x for x in range(1, 20)]
list_2 = [x ** 2 for x in range(1, 20)]


print(list_1)  # [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
print(list_2)  # [1, 4, 9, 16, 25, 36, 49, 64, 81, 100, 121, 144, 169, 196, 225, 256, 289, 324, 361]

# 笛卡尔积型的列表推导式
list_3 = [(x, y) for x in range(1, 3)        # 1,2
                 for y in range(7, 10)]      # 7、8、9

                                             # 该表达式会先将1分别和7、8、9组合,然后再拿2和7、8、9组合,共6对
print(list_3)  # [(1, 7), (1, 8), (1, 9), (2, 7), (2, 8), (2, 9)]


list_4 = [x+y for x in range(1, 3)
                 for y in range(7, 10)]

print(list_4)   # [8, 9, 10, 9, 10, 11]

# 还可以添加if语句
l = [1, 3, 4, 33, 45, 36, 422, 34, 67, 23, -4, -7, -345, 46, -6, -45, 32, -8, -4, 67, -4]

list_5 = [x for x in l if x > 0]   # 只取出大于0的生成列表
print(list_5)                      # [1, 3, 4, 33, 45, 36, 422, 34, 67, 23, 46, 32, 67]

 

1、ElementTree库 ------- xml解析:

 Selenium是三个Web的自动化测验工具,最先是为网址自动化测量检验而支付的,类型像大家玩游戏用的开关Smart,可以按钦定的下令自动操作,分歧是Selenium 可以直接运营在浏览器上,它援助全数主流的浏览器(满含PhantomJS那一个无分界面包车型客车浏览器)。

运营前边世了难题:ord() expected string of length 1, but int found

生成器表达式

# 虽然列表推导式可以用来初始化元组、数组或其他序列类型,但是列表推导式会直接生成列表,占用内存
# 而生成器遵守了迭代器协议,可以逐个产出元素,而不是先建立一个完整的列表


# 生成器表达式直接将推导式的方括号换成圆括号即可

g = (x for x in range(1, 10000))

print(g)    # <generator object <genexpr> at 0x105c0efc0> :生成器对象


from collections import Iterable, Iterator

if isinstance(g, Iterable):
    print("iterable")          # 输出iterable: 说明生成器g是可迭代的

if isinstance(g, Iterator):
    print("iterator")          # 输出iterator:说明生成器g是迭代器

 

  下边我们来比较一下列表推导式和生成器的效用

# 比较列表推导式和生成器
import time

start_time = time.time()
l = [x for x in range(1000000)]
print(time.time() - start_time)     # 0.1361069679260254

start_time = time.time()
g = (x for x in range(1000000))
print(time.time() - start_time)     # 1.1205673217773438e-05

# 可见,生成器远快于推导式

 

    • 导入ElementTree,import xml.etree.ElementTree as ET
    • 剖判Xml文件找到根节点:
    • 平昔分析XML文件并获得根节点,tree = ET.parse('country_data.xml') root = tree.getroot()
    • 剖判字符串,root = ET.fromstring(country_data_as_string)
    • 遍历根节点能够获取子节点,然后即可依据供给获得供给的字段了,如:<应用程式_KEY channel = 'CSDN'> hello123456789 </APP_KEY>
      • tag,即标签,用于标志该因素表示哪一类多少,即应用软件_KEY
      • attrib,即属性,用Dictionary方式保存,即{'channel' = 'CSDN'}
      • text,文本字符串,能够用来存款和储蓄一些数额,即hello123456789
      • long8,tail,尾字符串,并不是必得的,例子中未有满含。

Selenium 能够根据大家的授命,让浏览器自动加载页面,获取需求的多寡,乃至页面截屏,只怕推断网址上某个动作是否产生。

由此出现那些主题材料,是在字符串变换进度中冒出了一个小错误,在一雨后春笋百度和Google后,开掘概念依旧很迷糊,不过在曙光大佬的解答后,精通了怎么管理,正是在s后加””,运营后开掘完美消除

元组拆包

# 我们经常这样给两个变量同时赋值
a, b = 1, 2
print(a, b)     # 1 2

# 还可以这样
a, b = [1, 2]
print(a, b)     # 1 2

# 也可以这样
a, b = (1, 2)
print(a, b)     # 1 2

# 甚至可以这样
a, b = "ab"
print(a, b)     # a b

'''
    像以上这样连续的赋值方式,右边可以使用逗号隔开;也可以是序列。

    当拆包赋值的是序列时,python解释器会先找该序列中的__iter__方法,如果该方法不存在,则寻找__getitem__方法。

    接下来说其他用法
'''

# 赋值后优雅地交换两个变量
a, b = (1, 2)
a, b = b, a
print(a, b)        # 2 1

# 使用*号来处理多余的数据
a, b, *s = [1, 2, 3, 4, 5, 6, 7, 8, 9]
print(a, b, s)        # 1 2 [3, 4, 5, 6, 7, 8, 9]
                      # 这样从第三个元素开始的所有值都赋给了s

a, b, *s = (1, 2, 3, 4, 5, 6, 7, 8, 9)
print(a, b, s)        # 1 2 [3, 4, 5, 6, 7, 8, 9]
                      # 注意,本来是元组,赋之后的s变成了列表. 如果s为空的话也会返回空列表

*s, a, b = (1, 2, 3, 4, 5, 6, 7, 8, 9)
print(s, a, b)        # [1, 2, 3, 4, 5, 6, 7] 8 9
                      # *s也可以放在前面

a, *s, b = (1, 2, 3, 4, 5, 6, 7, 8, 9)
print(a, s, b)        # 1 [2, 3, 4, 5, 6, 7, 8] 9
                      # *s也可以放在中间

# 嵌套元组拆包
a, b, (c, d) = (1, 2, (3, 4))
print(a, b, c, d)     # 1 2 3 4
                      # 只要按照右边的形式就可赋值

a, b, *c = (1, 2, (3, 4))
print(a, b, c)     # 1 2 [(3, 4)]

 

long8 3long8 4

 1 ################################
 2 #
 3 # 以下的例子用以说明拆包赋值时,解释器会按照__iter__、__getitem__的顺序调用类中的方法
 4 #
 5 ################################
 6 class Foo:
 7     def __init__(self, s):
 8         self.s = s
 9 
10     def __iter__(self):
11         print("iter")
12         return iter(self.s)
13 
14     def __getitem__(self, item):
15         return self.s[item]
16 
17 if __name__ == "__main__":
18     foo = Foo("sdfafasfasf")
19     a, b, *s = foo
20     print(a, b)

拆包赋值的中间贯彻

 

  从前我们经过源码已经比较过list和tuple类中的方法和品质,上面列出《流畅的python》整理的列表和元组的章程及质量:

表 列表或元组的不二等秘书技和质量

  列  表 元  组
s.__add__(s2)
· ·
s.__iadd__(s2) ·  
s.append(e) ·  
s.clear() ·  
s.__contains__(e) · ·
s.copy() ·  
s.count(e) · ·
s.__delitem__(p) ·  
s.extend(it) ·  
s.__getitem__(p) · ·
s.__getnewargs__()   ·
s.index(e) · ·
x.insert(p,e) ·  
s.__iter__() · ·
s.__len__() · ·
s.__mul__(n) · ·
s.__imul__(n) ·  
s.__rmul__(n) · ·
s.pop([p]) ·  
s.remove(e) ·  
s.reverse() ·  
s.__reversed__() ·  
s.__setitem__(p,e) ·  
s.sort([key], [reverse]) ·  

   

  表达:以上元节组中不加黑点的不意味着决不能如此使用,只是其成效和列表差异(表达里面有表明)。比如八个元组a和b实行增量赋值a+=b也是能够的,只是这些操作不是就地拼接,而是生成了新的元组。

2、difflib库 ------- 提供的类和章程用来开展系列的差别化相比,它亦可比对文件并扭转差别结果文本或许html格式的差距化比较页面

Selenium 自个儿不带浏览器,不协助浏览器的法力,它需求与第三方浏览器结合在联合签字工夫使用.

切片

'''
    在python中,内置的序列类型都支持切片操作,切片操作的用法十分简单:
    list[start: stop: step]    , 其中不包括区间范围内最后一个(事实上这是python的风格,一般不包含区间最后一个)
    python里面能使用切片操作是因为实现了__getitem__方法,切片时会给该方法传递slice(start: stop: step) 参数
'''

if __name__ == "__main__":
    # 基本操作
    l = [1, 2, 3, 4, 5, 6, 7, 8, 9]
    print(l[2:])     # 第3个元素到最后   :[3, 4, 5, 6, 7, 8, 9]
    print(l[:3])     # 第一个元素到最后   :[1, 2, 3]

    s = "abcdefghijklmn"
    print(s[2::2])   # 从第三个字母开始,隔一个字母取一个 : cegikm
    print(s[::-1])   # 倒序排列 : nmlkjihgfedcba
    print(s[::-2])   # 倒序隔一个取一个 nljhfdb
    print(s[-2::-2]) # 倒序第二隔开始,隔一个取一个

    # 利用切片赋值
    l[2:5] = [20, 30]
    print(l)         # [1, 2, 20, 30, 6, 7, 8, 9]
    try:
        l[2:5] = 40      # 报错:TypeError: can only assign an iterable
                         # 利用切片赋值时传入的必须是可迭代对象
    except Exception as e:
        print(e)         # can only assign an iterable
    l[2:5] = (40,)
    print(l)             # [1, 2, 40, 7, 8, 9]
    l[2:3] = "sajfljls"  # 字符串属于序列,也可以迭代
    print(l)             # [1, 2, 's', 'a', 'j', 'f', 'l', 'j', 'l', 's', 7, 8, 9]

 

此间运用了类difflib.HtmlDiff,用来创制贰个html表格彰显文件差距,他不仅可以够开展全文本展示,也能够只浮现上下文不一致。

下载selenium webdriver ‘geckodriver.exe’,下载好后放到python目录里面

排序(list.sort方法和sorted函数)

'''
    list.sort方法和sorted内置函数都有排序的功能,区别如下
        list.sort是就地排序列表,不会把原列表复制一份。该方法返回None,以提醒不会新建一个列表。
        sorted函数会新建一个列表作为返回值,这个函数可以接受任何可迭代对象,甚至包括不可变序列或生成器,最后返回的总是列表。

    list.sort和sorted都有两个参数:
        reverse:默认为False,设定为True以降序排列
        key:一个只有一个参数的函数,这个函数会作用于序列的每一个元素上,然后以该函数的结果作为关键字排序

'''

if __name__ == "__main__":
    # 1、list.sort就地排序,而sorted返回列表
    l = [x for x in range(10, 0, -1)]      # 初始化一个列表:[10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
    print(id(l), l)    # l最初的地址:4536449800 [10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
    l.sort()
    print(id(l), l)    # 排序后的地址:4536449800 [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
                       # l前后的的地址没变,说明是就地排序


    l = [x for x in range(10, 0, -1)]  # 初始化一个列表:[10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
    print(id(l), l)  # l最初的地址:4415318984 [10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
    l = sorted(l)
    print(id(l), l)  # 排序后的地址:4415318792 [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

    # 2、sorted可以接受任何可迭代对象
    l = (x for x in range(10, 0, -1))
    print(type(l))        # 迭代器 <class 'generator'>
    print(sorted(l))      # [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

    s = "qwertyuiopasdfghjklzxcvbnm"   # 字符串序列
    print(sorted(s))      # ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z']

    s = (1, 3, 2, 456, 345, 12, 2, 5, 78, 34)   # 不可变元组
    print(sorted(s))      # [1, 2, 2, 3, 5, 12, 34, 78, 345, 456]

    # 3、reverse参数
    s = "qwertyuiopasdfghjklzxcvbnm"
    print(sorted(s, reverse=True))   # ['z', 'y', 'x', 'w', 'v', 'u', 't', 's', 'r', 'q', 'p', 'o', 'n', 'm', 'l', 'k', 'j', 'i', 'h', 'g', 'f', 'e', 'd', 'c', 'b', 'a']


    # 4、key参数
    s = "QwERTYuioPaSdfGHjKLzXcvbnm"
    print(sorted(s))    # ['E', 'G', 'H', 'K', 'L', 'P', 'Q', 'R', 'S', 'T', 'X', 'Y', 'a', 'b', 'c', 'd', 'f', 'i', 'j', 'm', 'n', 'o', 'u', 'v', 'w', 'z']
    print(sorted(s, key=str.lower))   # 忽略大小写 ['a', 'b', 'c', 'd', 'E', 'f', 'G', 'H', 'i', 'j', 'K', 'L', 'm', 'n', 'o', 'P', 'Q', 'R', 'S', 'T', 'u', 'v', 'w', 'X', 'Y', 'z']
    print(sorted(s, key=str.upper))   # 也是忽略大小写
##########################
#
#  以下自定义一个类也可使用sorted函数
#
##########################

class Obj:
    def __init__(self):
        self.s = [x for x in range(10, 0, -1)]

    def __getitem__(self, item):
        print("getitem")
        return self.s[item]

    def __repr__(self):
        return str(self.s)

    def __iter__(self):
        return iter(self.s)

obj = Obj()
print(obj)           # [10, 9, 8, 7, 6, 5, 4, 3, 2, 1]

# 添加getitem后可以使用sorted函数  (实验时请注视掉getitem方法)
print(sorted(obj))   #  打印10次getitem   , [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

# 添加iter方法
print(sorted(obj))   # 此时解释器会先调用iter方法,不会再使用getitem方法
                     # [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
使自定义类也可使用sorted函数调用

 

其构造函数如下:

firefox的目录也要加多各情状变量中

bisect

'''
    bisect模块主要用来管理有顺序的序列
    bisect模块包含的主要函数是bisect和insort,两个函数都使用二叉树方法搜索
    1、bisect(haystack, needle)
        haystack必须是一个有序的序列,该函数搜索needle在haystack中的位置,该位置使得将needle插入后haystack仍然升序
        查找到位置后可用haystack.insert()插入

    2、insort(seq, item)
        把item插入到seq中,并能保持seq的升序

'''

#  本人认为《流畅的python》中的对该模块介绍的例子比较经典,故引用之

# 1、关于bisect.bisect的示例
import bisect
import sys

HAYSTACK = [1, 4, 5, 6, 8, 12, 15, 20, 21, 23, 23, 26, 29, 30]
NEEDLES = [0, 1, 2, 5, 8, 10, 22, 23, 29, 30, 31]

ROW_FMT = '{0:2d} @ {1:2d}    {2}{0:<2d}'

def demo(bisect_fn):
    for needle in reversed(NEEDLES):
        position = bisect_fn(HAYSTACK, needle)
        offset = position * '  |'
        print(ROW_FMT.format(needle, position, offset))


if __name__ == '__main__':

    if sys.argv[-1] == 'left':
        bisect_fn = bisect.bisect_left
    else:
        bisect_fn = bisect.bisect

    print('DEMO:', bisect_fn.__name__)
    print('haystack ->', ' '.join('%2d' % n for n in HAYSTACK))
    demo(bisect_fn)


    '''   输出如下
    DEMO: bisect
    haystack ->  1  4  5  6  8 12 15 20 21 23 23 26 29 30
    31 @ 14      |  |  |  |  |  |  |  |  |  |  |  |  |  |31
    30 @ 14      |  |  |  |  |  |  |  |  |  |  |  |  |  |30
    29 @ 13      |  |  |  |  |  |  |  |  |  |  |  |  |29
    23 @ 11      |  |  |  |  |  |  |  |  |  |  |23
    22 @  9      |  |  |  |  |  |  |  |  |22
    10 @  5      |  |  |  |  |10
     8 @  5      |  |  |  |  |8 
     5 @  3      |  |  |5 
     2 @  1      |2 
     1 @  1      |1 
     0 @  0    0 
    '''
# 另,bisect.bisect函数有两个可选参数——lo和hi来缩小搜索范围,lo的默认值是0,hi的默认值是序列的长度
# 再另,bisect.bisect函数其实是bisect_right函数的别名,还有一个bisect_left,插入位置如果有相等的元素时,插入元素会放在它相等的
#      元素后面,后者会放在前面


# 根据分数,查到等级

def grade(score, breakpoints=[60, 70, 80, 90], grades = 'FDCBA'):
    i = bisect.bisect(breakpoints, score)     # 这里的bisect.bisect实际上使用的是bisect_right
    return grades[i]

print([grade(score) for score in [33, 55, 90, 87, 65, 78, 34, 60, 100]])

# 2、关于bisect.insort函数

import bisect
import random

SIZE = 7

random.seed(1729)

my_list = []
for i in range(SIZE):
    new_item = random.randrange(SIZE*2)
    bisect.insort(my_list, new_item)
    print('%2d ->' % new_item, my_list)

    '''输出:
    10 -> [10]
     0 -> [0, 10]
     6 -> [0, 6, 10]
     8 -> [0, 6, 8, 10]
     7 -> [0, 6, 7, 8, 10]
     2 -> [0, 2, 6, 7, 8, 10]
    10 -> [0, 2, 6, 7, 8, 10, 10]
    '''

# 另,insort函数也有insort_left,背后使用的是bisect_left

 

__init__(tabsize=8, wrapcolumn=None, linejunk=None, charjunk=IS_CHARACTER_JUNK)

Selenium Curry有个叫 WebDriver 的 API。WebDriver 有一些儿像能够加载网址的浏览器,但是它也足以像 BeautifulSoup 只怕其余 Selector 对象同样用来寻觅页面成分,与页面上的要素举办交互 (发送文书、点击等),以至推行别的动作来运营互连网爬虫。

本文由long8发布于long8,转载请注明出处:Selenium模拟顾客操作,搭建虚构主机步骤

上一篇:long8:率先篇小说,Python之函数计算 下一篇:没有了
猜你喜欢
热门排行
精彩图文