selenium中的Actionchains方法使用

273 阅读3分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第8天,点击查看活动详情 最近做的项目中用到的selenium比较多,今天分享一下selenium最常用的ActionChains的使用,以及碰到的一些问题的解决

1.selenium解决鼠标悬停的问题

今天抓取某个平台的数据时发现有的数据需要鼠标悬停在上面才能加载出来,于是就想到了使用ActionChains解决悬停的问题,下面是思路和举例:

首先需要定位到需要悬停的元素位置,然后使用ActionChains悬停,我这里使用的是xpath定位,有些网站可能会出现xpath定位不准的的情况,这个时候就需要切换使用css定位,定位到了以后就使用ActionChains中的move_to_element方法实现鼠标的移动,最后加上perform执行所有的操作,下面是使用方法

menu = self.wait.until(EC.presence_of_element_located((By.XPATH, ''xpath语法)) # 定位鼠标要悬停的元素
mouse = ActionChains(self.driver)
mouse.move_to_element(menu).perform()

2.selenium解决滑块拖动的问题

之前的文章中也提到过,使用selenium拖动滑块,这里需要注意的是滑块的拖动如果太快可能就会失败,所以咋拖动之前最好模拟生成一下滑块的轨迹,然后再去拖动,这里举个实例:

def get_list_x(self):
    """
    的到滑块轨迹
    :param distance:
    :param t:
    :return:
    """
    times = [1, 1.1, 1.3, 1.4, 1.7, 1.5, 1.8, 0.9, 1.6]
    t = random.choice(times)
    track = []
    current = 0
    mid = 258 * t / (t + 1)
    v = 0
    while current < 258:
        if current < mid:
            a = 3
        else:
            a = -1
        v0 = v
        v = v0 + a * t
        move = v0 * t + 1 / 2 * a * t * t
        current += move
        track.append(round(move))
    return track

def check_block(self, data, listx):
    """
    检测滑块
    :return:
    """
    try:
        while '亲,请拖动下方滑块完成验证' in data:
            action = ActionChains(self.driver)
            hk_button = self.driver.find_element(By.XPATH, '//*[@id="nc_1_n1z"]')
            for x in listx:
                action.click_and_hold(hk_button)
                action.move_by_offset(xoffset=x, yoffset=random.randint(0, 2))
                action.perform()
                action.release()
            time.sleep(1)
            self.driver.refresh()
            time.sleep(1)
    except:
        time.sleep(1)

这里我定义了两个函数,一个用于检测滑块,另外一个用于滑块的拖动,这里需要注意的是,在我之前的文章分享中我是使用的drag_and_drop_by_offset方法拖动,这里却是使用move_by_offset,这是因为move_by_offset能实现连续的拖动,但是drag_and_drop_by_offset却只能实现拖动到指定的位置后松开,这就很容易会被检测出来是爬虫

3.selenium中ActionChains的详细使用方法

click(on_element=None) ——单击鼠标左键

click_and_hold(on_element=None) ——点击鼠标左键,不松开

context_click(on_element=None) ——点击鼠标右键

double_click(on_element=None) ——双击鼠标左键

drag_and_drop(source, target) ——拖拽到某个元素然后松开

drag_and_drop_by_offset(source, xoffset, yoffset) ——拖拽到某个坐标然后松开

key_down(value, element=None) ——按下某个键盘上的键

key_up(value, element=None) ——松开某个键

move_by_offset(xoffset, yoffset) ——鼠标从当前位置移动到某个坐标

move_to_element(to_element) ——鼠标移动到某个元素

move_to_element_with_offset(to_element, xoffset, yoffset) ——移动到距某个元素(左上角坐标)多少距离的位置

perform() ——执行链中的所有动作

release(on_element=None) ——在某个元素位置松开鼠标左键

send_keys(keys_to_send) ——发送某个键到当前焦点的元素

send_keys_to_element(element, keys_to_send) ——发送某个键到指定元素

4.使用selenium时遇到的问题

之前的文章里面有分享过可以去看看,无非是Chromedriver的版本问题以及定位的问题,定位的问题上面提到过了,xpath不行就换css定位,一般来说css定位的准确性还是很高的,另外selenium中也有其他的定位方法,例如根据Class和ID定位的,chromdriver的问题之前的文章里有提到怎么下载对应版本的Chromedriver。