zoukankan      html  css  js  c++  java
  • 爬虫之selenium模块

    引入

    selenium最初是一个自动化测试工具,而爬虫中使用它主要是为了解决requests无法直接执行JavaScript代码的问题

    selenium本质是通过驱动浏览器,完全模拟浏览器的操作,比如跳转、输入、点击、下拉等,来拿到网页渲染之后的结果,可支持多种浏览器

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

    官网:http://selenium-python.readthedocs.io

    安装

     

    安装selenium:pip install selenium

    下载驱动浏览器驱动:

      有界面浏览器:Chrome ,Firefox(geckodriver)

      无界面浏览器:PhantomJS

    验证:

    from selenium import webdriver
    
    driver=webdriver.Chrome() # 弹出谷歌浏览器
    driver.get('https://www.baidu.com')
    driver.page_source

    基本使用

    from selenium import webdriver
    from selenium.webdriver.common.by import By #按照什么方式查找 ID/CSS
    from selenium.webdriver.common.keys import Keys #键盘按键操作
    from selenium.webdriver.support import expected_conditions as EC
    from selenium.webdriver.support.wait import WebDriverWait #等待页面加载某些元素
    import time
    
    browser=webdriver.Chrome()
    try:
        browser.get('https://www.jd.com')
        input_tag=browser.find_element_by_id('key')
        input_tag.send_keys('电脑')
        input_tag.send_keys(Keys.ENTER)
        wait=WebDriverWait(browser,10)
        wait.until(EC.presence_of_element_located((By.ID,'J_goodsList'))) #等到id为J_goodsList的元素加载完毕,最多等10秒
        # time.sleep(3)
    finally:
        browser.close()

    元素定位

    寻找元素主要有两种:

    find_element_   # 只匹配一个元素
    find_elements_  # 匹配所有元素的列表

    如果没有匹配到元素,selenium模块会抛出NoSuchElement异常

    获取到了WebElement对象,则可以获取对象的属性

    延时等待

     selenium只是模拟浏览器的行为,而浏览器解析页面是需要时间的(执行css,js),一些元素可能需要过一段时间才能加载出来,为了保证能查找到元素,必须等待

     等待的方式分两种:

    隐式等待:在browser.get('xxx')前就设置,针对所有元素有效

    from selenium import webdriver
    from selenium.webdriver.common.by import By #按照什么方式查找,By.ID,By.CSS_SELECTOR
    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()
    
    #隐式等待:在查找所有元素时,如果尚未被加载,则等10秒
    browser.implicitly_wait(10)
    
    browser.get('https://www.baidu.com')
    
    
    input_tag=browser.find_element_by_id('kw')
    input_tag.send_keys('美女')
    input_tag.send_keys(Keys.ENTER)
    
    contents=browser.find_element_by_id('content_left') #没有等待环节而直接查找,找不到则会报错
    print(contents)
    
    browser.close()
    隐式等待

    显式等待:在browser.get('xxx')之后设置,只针对某个元素有效

    from selenium import webdriver
    from selenium.webdriver.common.by import By #按照什么方式查找,By.ID,By.CSS_SELECTOR
    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()
    browser.get('https://www.baidu.com')
    
    
    input_tag=browser.find_element_by_id('kw')
    input_tag.send_keys('美女')
    input_tag.send_keys(Keys.ENTER)
    
    
    # 显式等待:显式地等待某个元素被加载
    wait=WebDriverWait(browser,10)
    wait.until(EC.presence_of_element_located((By.ID,'content_left')))
    
    contents=browser.find_element(By.CSS_SELECTOR,'#content_left')
    print(contents)
    
    
    browser.close()
    显示等待

    元素交互操作

    from selenium import webdriver
    import time
     
    browser = webdriver.Chrome()
    browser.get('https://www.taobao.com')
    input = browser.find_element_by_id('q')
    input.send_keys('诺基亚')
    time.sleep(1)
    input.clear()
    input.send_keys('IPhone')
    button = browser.find_element_by_class_name('btn-search')
    time.sleep(2)
    button.click()
    输入,清空
    from selenium import webdriver
    from selenium.webdriver import ActionChains
    import time
    
    browser = webdriver.Chrome()
    url = 'http://www.runoob.com/try/try.php?filename=jqueryui-api-droppable'
    browser.get(url)
    browser.switch_to.frame('iframeResult')
    source = browser.find_element_by_css_selector('#draggable')
    target = browser.find_element_by_css_selector('#droppable')
    actions = ActionChains(browser)
    # actions.drag_and_drop(source, target)
    actions.click_and_hold(source).perform()
    time.sleep(1)
    actions.move_to_element(target).perform()
    time.sleep(1)
    actions.move_by_offset(xoffset=50,yoffset=0).perform()
    
    actions.release()
    拖拽操作
    from selenium import webdriver
     
    browser = webdriver.Chrome()
    browser.get('https://www.jd.com/')
    browser.execute_script('window.scrollTo(0, document.body.scrollHeight)')
    browser.execute_script('alert("123")')
    执行JavaScript
    from selenium import webdriver
    from selenium.webdriver.common.by import By #按照什么方式查找,By.ID,By.CSS_SELECTOR
    from selenium.webdriver.support import expected_conditions as EC
    from selenium.webdriver.support.wait import WebDriverWait #等待页面加载某些元素
    
    browser=webdriver.Chrome()
    
    browser.get('https://www.amazon.cn/')
    
    wait=WebDriverWait(browser,10)
    wait.until(EC.presence_of_element_located((By.ID,'cc-lm-tcgShowImgContainer')))
    
    tag=browser.find_element(By.CSS_SELECTOR,'#cc-lm-tcgShowImgContainer img')
    
    #获取标签属性,
    print(tag.get_attribute('src'))
    #获取标签ID,位置,名称,大小(了解)
    print(tag.id)
    print(tag.location)
    print(tag.tag_name)
    print(tag.size)
    
    
    browser.close()
    获取节点信息

    其他操作

    import time
    from selenium import webdriver
    
    browser=webdriver.Chrome()
    browser.get('https://www.baidu.com')
    browser.get('https://www.taobao.com')
    browser.get('http://www.peng104.xyz')
    
    browser.back()
    time.sleep(10)
    browser.forward()
    browser.close()
    模拟浏览器前进后台
    from selenium import webdriver
    
    browser=webdriver.Chrome()
    browser.get('https://www.zhihu.com/explore')
    print(browser.get_cookies())
    browser.add_cookie({'k1':'xxx','k2':'yyy'})
    print(browser.get_cookies())
    
    # browser.delete_all_cookies()
    cookies
    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(10)
    browser.switch_to_window(browser.window_handles[0])
    browser.get('http://www.peng104.xyz')
    browser.close()
    选项卡管理
    from selenium import webdriver
    from selenium.common.exceptions import TimeoutException,NoSuchElementException,NoSuchFrameException
    
    try:
        browser=webdriver.Chrome()
        browser.get('http://www.runoob.com/try/try.php?filename=jqueryui-api-droppable')
        browser.switch_to.frame('iframssseResult')
    
    except TimeoutException as e:
        print(e)
    except NoSuchFrameException as e:
        print(e)
    finally:
        browser.close()
    异常处理

    来个小栗子

    from selenium import webdriver
    
    # 初始化driver
    driver = webdriver.Chrome()
    # 打开知乎登录页面
    driver.get('https://www.zhihu.com/signup')
    # 默认是注册界面,这里需要先找到切换登录的按钮
    signup_switch_bt = driver.find_element_by_xpath('//*[@id="root"]/div/main/div/div/div/div[2]/div[2]/span')
    # 如果内容显示登录,则证明在注册页面,需要点击一下切换到登录页面
    if signup_switch_bt.text == '登录':
        signup_switch_bt.click()
    # 找到填写用户名的输入框
    uname_textfield = driver.find_element_by_xpath(
        '//*[@id="root"]/div/main/div/div/div/div[2]/div[1]/form/div[1]/div[2]/div[1]/input')
    # 找到填写密码的输入框
    pwd_textfield = driver.find_element_by_xpath(
        '//*[@id="root"]/div/main/div/div/div/div[2]/div[1]/form/div[2]/div/div[1]/input')
    # 找到登录按钮
    signup_bt = driver.find_element_by_xpath('//*[@id="root"]/div/main/div/div/div/div[2]/div[1]/form/button')
    # 填写用户名,需要替换为你的用户名
    uname_textfield.send_keys('user_name')
    # 填写密码,需要替换为你的密码
    pwd_textfield.send_keys('your_password')
    # 点击登录
    signup_bt.click()
    自动登录知乎
  • 相关阅读:
    exports 和 module.exports 的区别
    (转) 前端模块化:CommonJS,AMD,CMD,ES6
    使用原生的javascript来实现轮播图
    使用C3的一些新属性绘制谷歌浏览器的图标
    仿照jQuery进行一些简单的框架封装(欢迎指教~)
    canvas中的非零环绕原则
    利用canvas进行一个饼形图的绘制
    利用构造函数对canvas里面矩形与扇形的绘制进行一个封装
    利用canvas来绘制一个会动的图画,欢迎指教
    自己整理出来的一些用到的方法的封装,欢迎指教
  • 原文地址:https://www.cnblogs.com/peng104/p/10323708.html
Copyright © 2011-2022 走看看