• 动态渲染页面爬取 【selenium】


    一.Selenium使用

       Selenium是一个自动化测试工具,利用它可以驱动浏览器执行特定的动作,如点击、下拉等

    操作,同时还可以获取浏览器当前呈现的页面的源代码,做到可见即可爬。对于一些Javascript
    动态渲染的页面来说,此种抓取方式非常有效。

    二.配置

     1.下载对应浏览器chromedrive将环境变量配置

      2.验证安装

      

     

       安装selenium

    pip3 install selenium

    三.基本使用

    from selenium import webdriver
    from selenium.webdriver.common.by import By
    from selenium.webdriver.common.keys import Keys
    from selenium.webdriver.support import expected_conditions as EC
    from selenium.webdriver.support.wait import WebDriverWait
    
    #创建浏览器对象
    browser = webdriver.Chrome()
    
    try:
        browser.get("http://www.baidu.com")
        input = browser.find_element_by_id("kw")
        input.send_keys("Python")
        input.send_keys(Keys.ENTER)
        wait = WebDriverWait(browser,10)
        wait.until(EC.presence_of_element_located((By.ID,'content_left')))
    
        current_url = browser.current_url
        cookie = browser.get_cookies()
        print(browser.page_source)
    
    finally:
        browser.close()

    四.步骤

      1.声明浏览器对象

    from selenium import webdriver
    
    browser = webdriver.Chrome()
    browser = webdriver.Firefox()
    browser = webdriver.Edge()
    browser = webdriver.PhantomJS()
    browser = webdriver.Safari()

       2.访问页面

    from selenium import webdriver
    
    #操作谷歌浏览器
    browser = webdriver.Chrome()
    #打开网站
    browser.get("http://www.baidu.com")
    #输出页面的源代码
    print(browser.page_source)
    #关闭浏览器
    browser.close()

       3.查找节点

    1.单个节点

    from selenium import webdriver
    
    #操作谷歌浏览器
    browser = webdriver.Chrome()
    #打开网站
    browser.get("http://www.baidu.com")
    
    #查找元素三种方式,
    #查找元素
    input_first = browser.find_element_by_id("kw")
    
    #选择器查找
    input_second = browser.find_element_by_css_selector("#kw")
    
    #xpath方式查找
    input_third = browser.find_element_by_xpath('//*[@id="kw"]')
    
    #输出
    print(input_first,input_second,input_third)
    
    #输出页面的源代码
    print(browser.page_source)
    #关闭浏览器
    browser.close()

     2.多个节点

    1.节点操作

      查找的元素如果就唯一,那么单个节点有效,但是多个就需要多个节点

      

    from selenium import webdriver
    
    from selenium.webdriver.common.by import By
    
    #操作谷歌浏览器
    browser = webdriver.Chrome()
    #打开网站
    browser.get("http://www.taobao.com")
    
    #查找元素
    lis = browser.find_elements_by_css_selector('.service-bd li')
    
    #也可以使用通用方法
    lis = browser.find_elements(By.CSS_SELECTOR,'.service-bd li')
    
    #输出页面的源代码
    print(browser.page_source)
    #关闭浏览器
    browser.close()

    2.节点交互

      selenium可以驱动浏览器来执行一些操作,也就是说可以让浏览器模拟执行一些动作。

      更多动作:http://selenium-python.readthedocs.io/api.html#moudle-selenium.webdriver.remote.webelement

    from selenium import webdriver
    
    import time
    
    #打开浏览器
    browser = webdriver.Chrome()
    
    url = "http://www.baidu.com"
    
    browser.get(url)
    
    #找到输入框
    input = browser.find_element_by_id("kw")
    
    #输入
    input.send_keys("草泥马")
    
    #等待1s
    time.sleep(1)
    
    #清除
    input.clear()
    
    input.send_keys("多么可爱")
    
    #点击百度一下按钮
    button = browser.find_element_by_class_name("s_btn")
    
    button.click()
    View Code

     3.动作链

      只有点击和输入还是不够的,还需要模拟鼠标的拖动,键盘按键等

    更多动作链:https://selenium-python.readthedocs.io/api.html#module-selenium.webdriver.common.action_chains

    from selenium import webdriver
    #导入动作链
    from selenium.webdriver import ActionChains
    
    browser = webdriver.Chrome()
    
    url = "http://www.runoob.com/try/try.php?filename=jqueryui-api-droppable"
    
    #打开网站
    browser.get(url)
    
    #框架iframe的id browser.switch_to.frame(
    'iframeResult') #找到起点和终点 source = browser.find_element_by_css_selector("#draggable") target = browser.find_element_by_css_selector("#droppable") #浏览器加载动作链 actions = ActionChains(browser) #创建起始位置和终点位置路径 action.drag_and_drop(source,target) #执行拖拽 actions.perform()

    webDriver只能在一个页面上对元素识别和定位,对于frame/iframe表单内嵌页面上的元素无法直接定位,此时就需要通过switch_to.frame()方法将当前定位的主题切换为iframe表单的内嵌页面中。

      4.执行JavaScript

      对于某些操作,selenium API并没有提供。比如,下拉进度条,它可以直接模拟运行JavaScript,此时使用

    execute_script()方法即可实现。

    from selenium import webdriver
    #导入动作链
    from selenium.webdriver import ActionChains
    
    browser = webdriver.Chrome()
    
    url = "http://www.zhihu.com/explore"
    
    #打开网站
    browser.get(url)
    
    browser.execute_script('window.scrollTo(0,document.body.scrollHeight)')
    
    browser.execute_script('alert("到底端了")')

     5.获取节点信息

      1.获取属性

    from selenium import webdriver
    #导入动作链
    from selenium.webdriver import ActionChains
    
    browser = webdriver.Chrome()
    
    url = "http://www.baidu.com"
    
    #打开网站
    browser.get(url)
    
    #找到logo id的节点
    logo = browser.find_element_by_id("lg")
    
    #输出属性
    print(logo)
    print(logo.get_attribute('class'))
    View Code

      2.获取文本

    获取文本相当于Beautifulsoup的get_text(),pyquery的text()

    from selenium import webdriver
    #导入动作链
    from selenium.webdriver import ActionChains
    
    browser = webdriver.Chrome()
    
    url = "http://www.baidu.com"
    
    #打开网站
    browser.get(url)
    
    #找到logo id的节点
    btn = browser.find_element_by_class_name("s_btn")
    
    #文本
    print(btn.text)

      3.获取id、位置、标签名和大小

    from selenium import webdriver
    #导入动作链
    from selenium.webdriver import ActionChains
    
    browser = webdriver.Chrome()
    
    url = "http://www.baidu.com"
    
    #打开网站
    browser.get(url)
    
    #找到logo id的节点
    btn = browser.find_element_by_class_name("s_btn")
    
    #获取id 位置 标签名和大小
    print(btn.id)
    print(btn.location)
    print(btn.tag_name)
    print(btn.size)

    6.切换Frame

              我们知道网页种有一种节点叫做iframe,也就是子Frame,相当于页面的子网页,它
    的结构和外部网页的结构完全一致。selenium打开页面后,它默认是在父级Frame里面
    操作,而此时如果页面中还有子Frame,它是不能获取到子Frame里面的节点的。这时
    就需要使用switch_to.frame()方法来切换Frame

    import time
    
    from selenium import webdriver
    
    from selenium.common.exceptions import NoSuchElementException
    
    #启动webdriver
    browser = webdriver.Chrome()
    
    #访问地址
    url = "http://www.runoob.com/try/try.php?filename=jqueryui-api-droppable"
    
    #打开网址
    browser.get(url)
    
    #进入框架
    browser.switch_to.frame('iframeResult')
    
    try:
        #找到元素类名为logo
        logo = browser.find_element_by_class_name('logo')
    except NoSuchElementException:
        print('No Logo')
        
    #切换到父级frame
    browser.switch_to.parent_frame()
    #找到类名为logo
    logo = browser.find_element_by_class_name('logo')
    print(logo)
    print(logo.text)

    7.延时等待

      在Selenium中,get()方法会在网页框架加载结束后结束执行,此时如果获取page_source,可能并不是浏览器完全加载完成的页面,如果某些页面有额外的Ajax请求,我们在网页源代码中也不一定能成功获取到。所以,这里需要延时等待一定时间,确保节点已经加载出来。

    1)隐式等待

        当使用隐式等待执行测试的时候,如果selenium没有在DOM中找到节点,将继续等待,超出设定时间后,则抛出找不到节点的异常,话句话说,当查找节点而节点并没有立即出现的时候,隐式等待将等待一段时间再查找DOM,默认的时间是0 

    from selenium import webdriver#启动webdriver
    browser = webdriver.Chrome()
    
    #访问地址
    url = "http://www.zhihu.com/explore"
    
    #使用implicitly_wait实现隐式等待
    browser.implicitly_wait(10)
    
    browser.get(url)
    
    input = browser.find_element_by_class_name('ExploreHomePage-ContentSection-header')
    
    print(input)

    2)显式等待

      隐式等待的效果其实并没有那么好,因为我们只规定了一个固定的时间,而页面的加载时间会受到网络条件的影响。这里还有一种更合适的显式等待方法,它指定要查找的节点,然后指定一个最长等待时间。如果在规定时间内加载出来了这个节点,就返回查找的节点;如果到了规定时间依然没有加载出该节点,则抛出超时异常

    from selenium import webdriver
    from selenium.webdriver.common.by import By
    from selenium.webdriver.support.ui import WebDriverWait
    from selenium.webdriver.support import expected_conditions as EC
    
    ##from selenium.common.exceptions import NoSuchElementException
    
    #启动webdriver
    browser = webdriver.Chrome()
    
    #访问地址
    url = "http://www.taobao.com/"
    browser.get(url)
    
    #引入WebDriverWait对象,指定最长等待时间
    wait = WebDriverWait(browser,10)
    
    #使用until()方法传入等待条件,节点
    input = wait.until(EC.presence_of_element_located((By.ID,'q')))
    
    #使用until()方法传入按钮可点击
    button = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR,'.btn-search')))
    
    
    print(input,button)

    显式等待和隐式等待的区别?

    8.前进和后退

    import time
    
    from selenium import webdriver
    
    browser = webdriver.Chrome()
    
    browser.get("http://www.baidu.com")
    
    browser.get("http://www.taobao.com")
    
    browser.get("http://www.zhihu.com")
    
    #返回
    browser.back()
    
    time.sleep(1)
    
    #前进
    browser.forward()
    
    browser.close()

    9.Cookie

      使用selenium,还可以方便地对cookie进行操作,例如获取、添加、删除Cookies等。

    from selenium import webdriver
    
    browser = webdriver.Chrome()
    
    browser.get("http://www.zhihu.com/explore")
    
    #打印cookie
    print(browser.get_cookies())
    
    #添加cookie
    browser.add_cookie({'name':'name','domain':'www.zhihu.com','value':'germey'})
    
    #获取cookie
    print(browser.get_cookies())
    
    #删除cookie
    browser.delete_all_cookies()
    
    print(browser.get_cookies())

    10.选项卡管理

      在访问网页的时候,会开启一个个选项卡。在selenium中,我们也可以对选项卡进行操作

    import time
    
    from selenium import webdriver
    
    browser = webdriver.Chrome()
    
    #打开网址
    browser.get("https://www.baidu.com")
    
    #打开一个选项卡
    browser.execute_script('window.open()')
    
    #输出此时选项卡句柄
    print(browser.window_handles)
    
    #将窗口转到新的选项卡
    browser.switch_to_window(browser.window_handles[1])
    browser.get("https://www.taobao.com")
    
    #等待
    time.sleep(1)
    
    #转到第一个选项卡
    browser.switch_to_window(browser.window_handles[0])
    
    browser.get("https://python.org")

     

    11.异常处理

        在使用selenium的过程中,难免会遇到一些异常,例如超时、节点未找到等错误,一旦出现此类错误,程序便不会继续执行了。这里我们可以

    使用try except语句来捕获各种异常。

    from selenium import webdriver
    from selenium.common.exceptions import TimeoutException,NoSuchElementException
    
    browser = webdriver.Chrome()
    
    try:
    
        browser.get("https://www.baidu.com")
    except TimeoutException:
        print("超时")
    try:
    
        browser.find_element_by_id('hello')
    except NoSuchElementException:
        print("没有此节点")
    finally:
        browser.close()

       

  • 相关阅读:
    【移动安全高级篇】————2、浅谈Android软件安全自动化审计
    【移动安全实战篇】————1、Android手机下xx.apk JAVA破解之旅
    【移动安全高级篇】————1、Android沙盘原理与实现
    CLR
    反射
    泛型
    面试
    Sqlite
    粒子
    地图
  • 原文地址:https://www.cnblogs.com/Crown-V/p/12735891.html
Copyright © 2020-2023  润新知