• 可见即可爬:Selenium


    Selenium是通过拖放控件的方式设计UI,设计是什么样,运行就是什么样。

    一.安装Selenium和WebDriver

    1.安装Selenium

    pip安装

    pip install selenium
    

    离线安装
    在该网址中找到https://www.lfd.uci.edu/~gohlke/pythonlibs/#lxmlselenium的包
    然后解压到该目录下,cmd命令cd到该目录下,执行如下命令

    pip install selenium‑3.141.0‑py3‑none‑any.whl
    

    2.安装WebDriver

    2.1Chrome版本的WebDriver称为ChromeDriver

    ChromeDriver的官网https://chromedriver.chromium.org/

    2.1.1使用ChromeDriver:

    下载下来的ChromeDriver.exe是一个可执行文件,要将ChromeDriver.exe文件添加到PATH环境变量中,这样在任何路径下都可以执行ChromeDriver。或者将下载下来的ChromeDriver放到指定目录下,在使用ChromeDriver时指定其路径即可

    2.1.2

    在python中使用ChromeDriver

    from selenium import webdriver
    browser = webdriver.Chrome()
    

    执行上述代码会立刻启动一个Chrome浏览器的实例,也可以通过Chrome类的构造方法指定ChromeDriver的路径

    from selenium import webdriver
    browser = webdriver.Chrome('./webdriver/ChromeDriver')
    

    2.2装Edge WebDriver

    下载地址https://developer.microsoft.com/en-us/microsoft-edge/tools/webdriver/

    2.2.1在python中使用Edge WebDriver

    from selenium import webdriver
    browser = webdriver.Edge()
    

    同样也可以指定Web WebDriver路径;可类比Chrome

    三.Selenium的基本使用方法

    3.1打开浏览器

    from selenium import webdriver
    browser = webdriver.Chrome('./webdriver/chromedriver')
    browser.get('https://www.jd.com')
    

    3.2控制浏览器页面的控件

    模拟按键,首先需要找到接收按键动作的节点
    Selenium支持多种方式查找节点,如通过id属性,通过class属性。然后可以通过send_keys方法模拟按键的动作

    from selenium import webdriver
    browser = webdriver.Chrome('./webdriver/chromedriver.exe')
    browser.get('https://www.jd.com')
    input = browser.find_element_by_id('key')
    input.send_keys('Python从菜鸟到高手')
    input.send_keys(Keys.ENTER)
    

    完整代码

    from selenium import webdriver
    from selenium.webdriver.common.keys import Keys
    from selenium.webdriver.common.by import By
    from selenium.webdriver.support.wait import WebDriverWait
    from selenium.webdriver.support import expected_conditions as ec
    browser = webdriver.Chrome('./webdriver/chromedriver.exe)
    try:
        browser.get('https://www.jd.com')
        # 根据id的属性值来查找搜索框
        input = browser.find_element_by_id('key')
        # 使用send_keys方法向搜索框中输入文本
        input.send_keys('Python从菜鸟到高手')
        # 使用send_keys方法按下ENTER键
        input.send_keys(Keys.ENTER)
        # 设置WebDriverWait对象,设置等待时间(4秒)
        wait = WebDriverWait(browser,4)
        # 等待搜索页面显示(通过查找id值为J_goodsList的节点判断搜索页面是否显示)
        wait.until(ec.presence_of_all_elements_located((By.ID,'J_goodsList')))
        # 显示搜索页面的标题
        print(browser.title)
        # 显示搜索页面的URL
        print(browser.current_url)
        # 显示搜索页面的代码
        print(browser.page_source)
        # 关闭浏览器
        browser.close()
    
    except Exception as e:
        print(e)
        browser.close()
    

    在上面代码使用了WebDriverWait类,该类是为了在执行的过程中等待一段时间,这里设置为4秒。这是由于按下ENTER键后,并不一定马上显示搜索结果,需要一定的延长,但python程序不会等待搜索结果出来再往下继续执行下去,就会造成python程序已经运行到处理搜索结果页面的位置时,搜索结果页面还没显示出来。所以使用WebDriverWait类的until方法判断搜索结果页面是否显示完成。

    wait = WebDriverWait(browser,4)
        # 等待搜索页面显示(通过查找id值为J_goodsList的节点判断搜索页面是否显示)
    wait.until(ec.presence_of_all_elements_located((By.ID,'J_goodsList')))
    

    四.查找节点

    4.1查找单个节点

    find_element开头的方法都是用于查找单个节点的API.
    如下图所示

    上述API列表可以看到,Selenium支持通过多种方式查找节点,如XPath、CSS选择器、class属性、id属性、标签名等。这些方法使用都一样,只是需要传入不同的参数值
    本例通过使用Selenium通过id属性、name属性、和class属性获取表单中特定的input节点,并自动输入表单的内容
    这里查找的网页是用服务器挂载的静态页面

    from selenium import webdriver
    from selenium.webdriver.common.by import By
    # 不支持本地网页
    browser = webdriver.Chrome('./webdriver/chromedriver')
    try:
        browser.get('http://localhost/demo.html')
        input = browser.find_element_by_id('name')
        input.send_keys('王军')
        input = browser.find_element_by_id('age')
        input.send_keys('30')
    
        input = browser.find_element_by_name('country')
        input.send_keys('中国')
    
        input = browser.find_element_by_class_name('myclass')
        input.send_keys('4000')
    
        # 或下面的代码
        input = browser.find_element(By.CLASS_NAME,'myclass')
        input.clear()  # 不清空  追加
        input.send_keys('8000')
    
    
    
    except Exception as e:
        print(e)
        browser.close()
    

    4.2查找多个节点

    查找多个节点返回的是一个列表,而查找单个节点返回的是一个节点
    若没有符合条件的节点,就会返回空列表
    这些API都是以find_elements开头的方法
    uploading-image-874268.png

    本例使用Selenium通过节点名查找所有符合条件的节点,并输入节点本身、符合条件的节点总数以及第一个符合条件的节点的文本

    from selenium import webdriver
    from selenium.webdriver.common.by import By
    # 不支持本地网页
    browser = webdriver.Chrome('./webdriver/chromedriver')
    try:
        browser.get('https://www.jd.com')
        input = browser.find_elements_by_tag_name('li')
    
        print(input)
        print(len(input))
        print(input[0].text)
        input = browser.find_elements(By.TAG_NAME,'ul')
        print(input)
        print(input[0].text)
        
        browser.close()
    
    except Exception as e:
        print(e)
        browser.close()
    

    4.5节点交互

    例如click方法可以模拟单击节点的动作
    本例使用Selenium通过模拟浏览器单击动作循环单击页面上的6个按钮,单击每个按钮后,按钮下方的div就会按照按钮的背景色设置div的背景色

    from selenium import webdriver
    import time
    
    browser = webdriver.Chrome('./webdriver/chromedriver')
    try:
        browser.get('http://localhost/demo1.html')
        buttons = browser.find_elements_by_class_name('mybutton')
        i = 0
        while True:
            buttons[i].click()
            time.sleep(1)
            i += 1
            if i == len(buttons):
                i = 0
    
    except Exception as e:
        print(e)
        browser.close()
    
    

    4.6动作链

    在前面的交互动作中,交互动作都是针对某个节点执行的,例如,对于某个input节点输入一个字符串、模拟单击某一个按钮等。但还有另外一类交互动作,他们没有特定的执行对象,比如鼠标拖拽、键盘按键等,其实这些动作相当于全局事件,需要另外一种方式执行,这就是动作链。
    动作链需要创建ActionChains对象,并通过ActionChains类的若干方法向浏览器发送一个或多个动作。
    本例会使用Selenium动作链的move_to_element方法模拟鼠标移动的动作,自动显示京东商城首页左侧的每个二级导航菜单。

    from selenium import webdriver
    from selenium.webdriver import ActionChains
    import time
    browser = webdriver.Chrome()
    try:
        browser.get('https://www.jd.com')
        # 创建一个ActionChains对象
        actions = ActionChains(browser)
        # 通过CSS选择器查找所有class属性值为cate_menu_item的li节点,每一个li节点
        # 是一个二级导航栏
    
        li_list = browser.find_elements_by_css_selector(".cate_menu_item")
        # 通过迭代,显示每一个二级菜单,调用动作链中方法发送动作后,必须调用preform方法才能生效
        for li in li_list:
            actions.move_to_element(li).perform()
            time.sleep(1)
    except Exception as e:
        print(e)
        browser.close()
    

    本例演示地址是https://www.runoob.com/try/try.php?filename=jqueryui-api-droppable,目的使用drag_and_drop方法将页面右侧的小方块拖到大方块上。

    from selenium import webdriver
    from selenium.webdriver import ActionChains
    
    browser = webdriver.Chrome('./webdriver/chromedriver')
    try:
        browser.get('http://www.runoob.com/try/try.php?filename=jqueryui-api-droppable')
        browser.switch_to.frame('iframeResult')
        source = browser.find_element_by_css_selector('#draggable')
        target = browser.find_element_by_css_selector('#droppable')
        actions = ActionChains(browser)
        # 调用drag_and_drop方法拖动节点
        actions.drag_and_drop(source, target)
        # 调用perform方法让拖动生效
        actions.perform()
    except Exception as e:
        print(e)
        browser.close()
    

    注意,如果页面存在iframe节点,而且要操作iframe中的节点,需要首先使用frame方法切换到iframe节点,才能操作里面的子节点。

    4.7执行JavaScript代码

    对于某些操作,Selenium并没有提供相应的API,例如,下拉页面,不过可以使用Selenium的execute_script方法直接运行JavaScript代码,以便扩展Selenium的功能。
    本例会使用Selenium的execute_script方法让京东商城首页滚动到最低端,然后弹出一个对话框。

    from selenium import webdriver
    browser = webdriver.Chrome('./webdriver/chromedriver')
    browser.get('https://www.jd.com')
    # 将京东商城滚动到最低端
    browser.execute_script('window.scrollTo(0,document.body.scrollHeight)')
    # 弹出对话框
    browser.execute_async_script('alert("已经到达页面底端")')
    

    4.8获取节点信息

    使用Selenium的API还可以获得详细的节点信息,如节点的位置,节点名称,节点尺寸和几点属性等。
    本例会使用Selenium的API获取京东商城首页HTML代码中id为navitems-groupl的ul节点的相关信息以及ul节点中li节点的相关信息

    from selenium import webdriver
    from selenium.webdriver import ActionChains
    options = webdriver.ChromeOptions()
    # 添加参数,不让Chrome浏览器显示,只在后台运行
    options.add_argument('headless')
    
    browser = webdriver.Chrome('./webdriver/chromedriver',chrome_options=options)
    #browser = webdriver.PhantomJS('./webdriver/phantomjs')
    browser.get('https://www.jd.com')
    # 查找页面中id属性值为navitems-group1的第一个节点
    ul = browser.find_element_by_id("navitems-group1")
    print(ul.text)
    print('id','=',ul.id)  # 内部id,不是节点id属性值
    print('location','=',ul.location)
    
    print('tag_name','=',ul.tag_name)
    print('size','=',ul.size)
    li_list = ul.find_elements_by_tag_name("li")
    for li in li_list:
        print(type(li))
        # 属性没找到,返回None
        print('<',li.text,'>', 'class=',li.get_attribute('class'))
        a = li.find_element_by_tag_name('a')
        print('href','=',a.get_attribute('href'))
    browser.close()
    

    五.管理Cookie

    使用Selenium,可以方便的管理Cookie,例如获取Cookie、添加和删除Cookie等
    本例使用Selenium API获取Cookie列表,并添加新的Cookie,以及删除所有的Cookie。

    from selenium import webdriver
    browser = webdriver.Chrome('./webdriver/chromedriver')
    browser.get('https://www.jd.com')
    # 为获取Cookie列表
    print(browser.get_cookies())
    # 添加新的Cookie
    browser .add_cookie({'name': 'name',
     'value':'jd','domain':'www.jd.com'})
    print(browser.get_cookies())
    # 删除所有的Cookie
    browser.delete_all_cookies()
    print(browser.get_cookies())  # 大部分删除了,可能还剩下一些
    

    六.管理节点的属性值

    Selenium本身并没有提供修改节点属性的API,不过可以通过执行JavaScript代码的方式设置节点属性,而且通过Selenium获取的节点可以直接作为DOM使用,这就意味着可以直接在JavaScript代码中使用查找到的节点。
    execute_script方法的第一个参数用于指定Javascript代码,后面的可变参数,可以为Javascript代码传递参数。通过arguments变量获取每一个参数值,例如arguments[0]表示第1个参数值,arguments[1]表示第2个参数值,以此类推。

    6.1本例会通过JavaScript代码改变百度搜索按钮的位置,让这个按钮在多个位置之间移动,时间间隔是2秒。

    from selenium import webdriver
    import time
    driver = webdriver.Chrome('./webdriver/chromedriver')
    driver.get("http://www.baidu.com")
    search_button = driver.find_element_by_id("su")  # 百度搜索按钮
    # arguments[0]对应的是第一个参数,可以理解为python里的%s传参,与之类似
    # 定义搜索坐标可以移动到x的坐标位置
    x_positions = [50,90,130,170]
    y_positions = [100,120,160,90]
    for i in range(len(x_positions)):
        # 用于移动的JavaScript代码,arguments[0]就是搜索按钮对应的DOM
        js = '''
         arguments[0].style.position = "absolute";
         arguments[0].style.left="{}px";
         arguments[0].style.top="{}px";
        '''.format(x_positions[i],y_positions[i])
        # 执行JS代码,并开始移动搜索按钮
        driver.execute_script(js, search_button)
        time.sleep(2)
    

    6.2本例使用JS代码修改京东商城首页顶端的前两个导航菜单的文本和链接,分别改成....。导航链接也会改变

    from selenium import webdriver
    import time
    driver = webdriver.Chrome('./webdriver/chromedriver')
    driver.get("https://www.jd.com")
    ul = driver.find_element_by_id('navitems-group1')
    li_list = ul.find_elements_by_tag_name('li')
    a1 = li_list[0].find_element_by_tag_name('a')
    a2 = li_list[1].find_element_by_tag_name('a')
    js = '''
     arguments[0].text = 'Python从菜鸟到高手'
     arguments[0].href = 'https://item.jd.com/12417265.html'
     arguments[1].text = '极客起源'
     arguments[1].href = 'https://geekori.com'
     '''
    driver.execute_script(js, a1,a2)
    

    12/13新增Webdriver常用方法

    通过partial_link_text(部分链接)文本来定位文本链接
    find_element_by_partial_link_text('字符串')
    通过完整链接文本link_text定位文本链接
    find_element_by_link_text('字符串')

    1.浏览器操作

    get() 访问URL driver.get('url链接')
    back 后退上一步 driver.back()
    forward 前进下一步 driver.forward()
    quit 退出驱动,关闭所有窗口 driver.quit()
    close 关闭当前打开的窗口 driver.close()
    maximize_window 浏览器最大化 driver.maximize_window()
    refresh 刷新浏览器 driver.refresh()
    

    2.元素操作

    send_keys() 向文本框类型输入数据 driver.find_element_by_tag('input').send_keys('selenium')
    clear() 清空输入的数据 driver.find_element_by_tag('input').clear()
    click() 单击事件 driver.find_element_by_tag('button').click()
    enter() 触发键盘enter操作 driver.find_element_by_tag('input').enter()
    text() 获取元素的文本内容 driver.find_element_by_partial_link_text('Outlook').text() 获取Outlook.com文本
    page_source 获取页面HTML内容 driver.page_source() ## 这句话非常有用,可以对抗任何反爬的措施,缘由是获取到了被浏览器渲染过后的网页源代码
    

    3.Cookie操作

    get_cookies() 获取当前页的所有Cookies driver.get_cookies()
    get_cookie(name) 获取当前页Cookies中的指定name值的cookie driver.get_cookies('time')
    add_cookie 添加Cookie driver.add_cookie({'time':'20211213121231'})
    delete_cookie(name) 删除一条Cookie driver.delete_cookie('time')
    delete_all_cookies 删除所有Cookie driver.delete_all_cookies()

    努力拼搏吧,不要害怕,不要去规划,不要迷茫。但你一定要在路上一直的走下去,尽管可能停滞不前,但也要走。
  • 相关阅读:
    Linux c 开发25 VScode C++ 运行中文乱码
    IEC104开发3 lib60870IEC 608705101 / 104 SOE
    Linux c 开发26 cmake生成项目
    STM32 例程7 STM32固件库方式 读取SHT20 温湿度
    基本电路学习1 12v转5V 电路
    github copilot 代码智能提示 AI代码提示
    Cesium polygon polyline entity label 贴地 点线面文本模型贴地 clampToGround 地面遮挡 地底遮挡 文字遮挡 道路遮挡 地形遮盖 地图遮盖
    UE4 HTTP REST 请求与高德天气预报接口 VaRest 插件
    UE4 蓝图截图 全屏截图 蓝图笔记截图 蓝图高清截图 蓝图保存插件 Blueprint Graph Screenshot(蓝图截图插件)
    window Carnac 实时显示键盘按键 桌面显示按钮 虚拟键盘 演示键盘 直播教学键盘
  • 原文地址:https://www.cnblogs.com/wkhzwmr/p/15236754.html
Copyright © 2020-2023  润新知