• 爬虫工具 - selenium


    一、selenium的基本使用

    1. 安装(换元安装):

            在CMD窗口中输入:pip install selenium -i http://pypi.douban.com/simple/ --trusted-host pypi.douban.com

             若提示pip命令不可以或安装失败,先使用命令 upgrade  pip 更新pip安装命令

    2. 案例 -- 打开百度输入“爬虫”搜索,并返回网页的一些信息

    1. from selenium import webdriver # 驱动浏览器
    2. from selenium.webdriver.common.by import By # 选择器
    3. from selenium.webdriver.common.keys import Keys # 按钮
    4. from selenium.webdriver.support.wait import WebDriverWait # 等待页面加载完毕
    5. from selenium.webdriver.support import expected_conditions as EC
    6. # 1.驱动浏览器
    7. brower = webdriver.Chrome()
    8. # 2.请求页面, --返回的数据封装在了browser对象里,不需要额外的变量接收
    9. brower.get("http://www.baidu.com") # 调用浏览器驱动访问站点
    10. # 3.拿到输入框
    11. # text_input = brower.find_element_by_id('kw') # 方法1,不建议使用!!!
    12. text_input = brower.find_element(By.ID, 'kw')
    13. # 4.向输入框中写入内容
    14. text_input.send_keys("爬虫")
    15. # 5.按下回车按钮
    16. text_input.send_keys(Keys.ENTER)
    17. # 等待事件,防止网速过慢
    18. wait = WebDriverWait(brower, 100) # 参数1:浏览器对象,参数2:时间
    19. # 等待某元素出现 presence_of_element_located()传入的参数格式是一个元组
    20. wait.until(EC.presence_of_element_located((By.ID, 'result_tts_player')))
    21. print(brower.current_url) # 查看网页url
    22. print(brower.get_cookies()) # 查看cookie信息
    23. print(brower.page_source) # 查看网页原码
    24. brower.close() # 关闭浏览器

    3. 声明不同的浏览器对象

    1. from selenium import webdriver
    2. browser = webdriver.Chrome() # 谷歌浏览器,一般都使用Chrome
    3. browser = webdriver.Firefox()
    4. browser = webdriver.PhantomJS()
    5. browser = webdriver.Safari()

    4. 访问页面

    1. from selenium import webdriver
    2. # 声明Chromeduix
    3. browser = webdriver.Chrome()
    4. # 请求页面
    5. browser.get("https://www.taobao.com")
    6. # 获取网页源代码
    7. print(browser.page_source)
    8. # 关闭浏览器
    9. browser.close()

    5. 查找元素

        (1)查找单个元素的方法:

                    find_element(By.ID,"id") 根据id属性来定位

                    find_element(By.NAME,"name") 根据name元素来定位

                    find_element(By.XPATH,"xpath语法") 根据xpath语法来定位

                    find_elemnt(By.TAG_NAME,"input") 根据标签名来定位

                    find_element(By.CLASS_NAME,"classname") 根据class的名字来定位

                    find_element(By.CSS_SELECTOR,"#id") 根据css选择器来定位

                    find_element(By.LINK_TEXT,"text") 根据文本属性

       案例1:

    1. from selenium import webdriver
    2. # 单个元素
    3. browser = webdriver.Chrome()
    4. browser.get("http://www.baidu.com")
    5. browser.find_element(By.LINK_TEXT, '新闻').click() # 通过.click()点击目标链接
    6. browser.close()

       案例2:

    1. browser = webdriver.Chrome()
    2. browser.get("http://www.taobao.com")
    3. # 1.通过元素ID查找
    4. by_id = browser.find_element(By.ID,'q')
    5. by_id.send_keys('美食')
    6. print(by_id)
    7. # 2.通过css选择器查找
    8. css_select = browser.find_element(By.CSS_SELECTOR,'#q')
    9. css_select.send_keys('美食')
    10. # 3.通过xpath查找
    11. xpath = browser.find_element(By.XPATH,'//*[@id="q"]')
    12. xpath.send_keys('美食')
    13. browser.close()

       (2)查找多个元素:

            find_elements(By.ID,"id") 根据id属性来定位

            find_elements(By.NAME,"name") 根据name元素来定位

            find_elements(By.XPATH,"xpath语法") 根据xpath语法来定位

            find_elemnts(By.TAG_NAME,"input") 根据标签名来定位

            find_elements(By.CLASS_NAME,"classname") 根据class的名字来定位

            find_elements(By.CSS_SELECTOR,"#id") 根据css选择器来定位

            find_elements(By.LINK_TEXT,"text") 根据文本属性

    案例:

    1. from selenium import webdriver # 驱动浏览器
    2. from selenium.webdriver.common.by import By # 选择器
    3. browser = webdriver.Chrome()
    4. browser.get("http://www.taobao.com")
    5. # 通过CSS选择器定位
    6. elements = browser.find_elements(By.CSS_SELECTOR, '.service-bd li')
    7. # print(elements) # 以列表形式返回
    8. for e in elements:
    9. print(e)

    6. 元素的交换操作

    案例:对获取的元素调用交换方法

    1. import time
    2. from selenium import webdriver # 驱动浏览器
    3. from selenium.webdriver.common.by import By # 选择器
    4. browser = webdriver.Chrome()
    5. browser.get("http://www.jd.com")
    6. text_input = browser.find_element(By.ID, 'key')
    7. text_input.send_keys("iphone")
    8. time.sleep(2)
    9. # 清空原来的文本内容
    10. text_input.clear()
    11. text_input.send_keys('iPad')
    12. # 找到按钮并单击
    13. button = browser.find_element(By.CLASS_NAME, 'button')
    14. button.click()
    15. browser.close()

    7. 交互动作ActionChains,将动作附加到动作链中串行执行

    1. from selenium import webdriver # 驱动浏览器
    2. from selenium.webdriver.common.by import By # 选择器
    3. browser = webdriver.Chrome()
    4. url = "http://www.runoob.com/try/try.php?filename=jqueryui-api-droppable"
    5. browser.get(url)
    6. """
    7. webDriver只能在一个页面上对元素识别和定位
    8. 对于frame/iframe表单内嵌页面上的元素无法直接定位,
    9. 此时就需要通过switch_to.frame()方法将当前定位的主题切换为iframe表单的内嵌页面中,
    10. switch_to.frame()默认可以直接提取表单的id和name属性
    11. """
    12. #.switch_to.frame()
    13. from selenium.webdriver import ActionChains
    14. browser.switch_to.frame('iframeResult') # 将当前定位的主题切换为iframe表单的内嵌页面中
    15. A = browser.find_element(By.CSS_SELECTOR, '#draggable')
    16. B = browser.find_element(By.CSS_SELECTOR, '#droppable')
    17. # 产生一个动作执行器
    18. actions = ActionChains(browser)
    19. actions.drag_and_drop(A, B) # A移动到B
    20. actions.perform() # 执行动作链
    21. browser.close()

    8. 执行JavaScript

     selenium并不是万能的,有时候页面上操作无法实现的,这时候就需要借助JS来完成了

            滚动页面方法execute_script() 该方法可调用原生JavaScript的api

            滚动到底部:window.scrollTo(0,document.body.scrollHeight)

            滚动到顶部:window.scrollTo(0,0)

      说明:

            window:js的window对象

            scrollTo:window的方法,可以滚到页面的任何位置

            scrollHeight:是dom元素的通用属性,document.body.scrollHeight会返回body元素的高度,基本上就是页面的高度

            scrollLeft:获取位于对象左边界和窗口目前可见内容的最左端之间的距离

            scrollTop:获取位于对象最顶端和窗口中可见内容的最顶端之间的距离

            scrollWidth:获取对象滚动的宽度

    案例:

    1. import time
    2. from selenium import webdriver # 驱动浏览器
    3. driver = webdriver.Chrome()
    4. driver.get('http://news.baidu.com')
    5. time.sleep(2)
    6. # 滚动到浏览器底部
    7. js = "window.scrollTo(0,document.body.scrollHeight)"
    8. driver.execute_script(js) # 执行js代码
    9. time.sleep(2)
    10. # 回到浏览器顶部
    11. js2 = "window.scrollTo(0,0)"
    12. driver.execute_script(js2)

    9. 获取元素信息

            获取文本及其属性 :.text文本值, get_attribute()根据属性获取属性值

    1. from selenium import webdriver # 驱动浏览器
    2. from selenium.webdriver.common.by import By # 选择器
    3. browser = webdriver.Chrome()
    4. url = "https://www.zhihu.com/explore"
    5. browser.get(url)
    6. # 知乎,圆桌讨论
    7. l = browser.find_element(By.CSS_SELECTOR, '.ExploreRoundtableCard.ExploreHomePage-roundtableCard .ExploreRoundtableCard-header .ExploreRoundtableCard-title')
    8. print(l)
    9. print("--------------------------------------")
    10. # 返回的l是列表类型,可以遍历返回
    11. # for i in l:
    12. # print(i)
    13. # print(i.text)
    14. # print(i.get_attribute('href'))
    15. # 找单个元素
    16. logo = browser.find_element(By.XPATH,'//*[@id="special"]/div[2]/div/div[3]/div[1]/div[1]/a')
    17. print(logo)
    18. print(logo.text)
    19. print(logo.get_attribute('href'))

    10. 等待

            等待特定元素出现后做某事,通常用于等待某个网页元素加载完毕后进行后续操作,避免出现异常。

    EC模块的使用方法:

            导包:from selenium.webdriver.support import expected_conditions as EC

            title_is 标题是某内容

            title_contains 标题包含某内容

            presence_of_element_located 元素加载出,传入定位元组,如(By.ID, 'p')

            visibility_of_element_located 元素可见,传入定位元组

            visibility_of 可见,传入元素对象

            presence_of_all_elements_located 所有元素加载出

            text_to_be_present_in_element 某个元素文本包含某文字

            text_to_be_present_in_element_value 某个元素值包含某文字

            frame_to_be_available_and_switch_to_it frame加载并切换

            invisibility_of_element_located 元素不可见

            element_to_be_clickable 元素可点击

            staleness_of 判断一个元素是否仍在DOM,可判断页面是否已经刷新

            element_to_be_selected 元素可选择,传元素对象

            element_located_to_be_selected 元素可选择,传入定位元组

            element_selection_state_to_be 传入元素对象以及状态,相等返回True,否则返回False

            element_located_selection_state_to_be 传入定位元组以及状态,相等返回True,否则返回False

             alert_is_present 是否出现Alert

    案例:

    1. from selenium import webdriver # 驱动浏览器
    2. from selenium.webdriver.common.by import By # 选择器
    3. from selenium.webdriver.support.wait import WebDriverWait # 等待页面加载完毕
    4. from selenium.webdriver.support import expected_conditions as EC
    5. browser = webdriver.Chrome()
    6. browser.get("http://www.taobao.com")
    7. wait = WebDriverWait(browser, 100)
    8. # 等待特定元素加载完
    9. input = wait.until(EC.presence_of_element_located((By.ID, 'J_Toolkit')))
    10. print(input)

    11. 前进后退

    1. import time
    2. from selenium import webdriver # 驱动浏览器
    3. browser = webdriver.Chrome()
    4. browser.get("http://www.baidu.com")
    5. browser.get("http://www.taobao.com")
    6. browser.get("http://www.jd.com")
    7. browser.back() # 后退 淘宝
    8. time.sleep(3)
    9. browser.forward() # 前进 京东
    10. time.sleep(3)

    12. 选项卡管理

            窗口切换 switch_to_window(窗口ID) switch_to.window(窗口ID) (python3.8以上版本都支持,python3.7只支持后者写法)

            查看所有窗口ID window_handles

            FAQ:只有切换到当前窗口时,才能操作当前窗口(比如翻页、获取源代码等等)

    案例:

    1. import time
    2. from selenium import webdriver # 驱动浏览器
    3. browser = webdriver.Chrome()
    4. browser.get("http://www.baidu.com")
    5. # 调用原生JavaScript的api接口
    6. browser.execute_script('window.open()') # 选项卡1 窗口1
    7. time.sleep(1)
    8. browser.execute_script('window.open()') # 选项卡2 窗口2
    9. print(browser.window_handles) # 查看当前浏览器所有窗口ID
    10. # 给新选项卡窗口访问目标站点 .switch.to.window
    11. browser.switch_to.window(browser.window_handles[0])
    12. browser.get('https://www.mi.com/')
    13. browser.switch_to.window(browser.window_handles[1]) #加载窗口2 切换到窗口2
    14. browser.get('https://www.taobao.com') # 窗口2 打开淘宝
    15. browser.switch_to.window(browser.window_handles[2])
    16. browser.get('https://jd.com')
    17. browser.switch_to.window(browser.window_handles[1])
    18. browser.page_source

    13. 异常处理

    异常处理模块所在位置:from selenium.common.exceptions import TimeoutException, NoSuchElementException

    案例:

    1. from selenium import webdriver # 驱动浏览器
    2. from selenium.webdriver.common.by import By # 选择器
    3. from selenium.common.exceptions import TimeoutException, NoSuchElementException
    4. browser = webdriver.Chrome()
    5. try:
    6. browser.get('https://www.baidu.com')
    7. except TimeoutException:
    8. print('Time out')
    9. try:
    10. browser.find_element(By.ID,'hello')
    11. except NoSuchElementException:
    12. print('No Element')
    13. finally: #无论try语句中是否抛出异常,finally中的语句一定会被执行
    14. browser.close()

    补充:

    设为开发者模式(无头模式),避免被监测导致爬虫失败,只需添加参数
            options = webdriver.ChromeOptions()   # 配置对象
            options.add_experimental_option('excludeSwitches', ['enable-automation'])   # 写入参数
            browser = webdriver.Chrome(options=options)
            browser.get('https://www.baidu.com')

  • 相关阅读:
    JavaScript面向对象:类的继承
    Java技术之高频面试题
    流量调度、微服务可寻址性和注册中心
    QT 字符串操作常用接口函数
    Tomcat深入浅出——Filter与Listener(五)
    java判断对象是否还在被引用
    基于SSM的家居商城系统
    redis群集
    【Python】OS 模块简介
    弱监督语义分割CLIMS
  • 原文地址:https://blog.csdn.net/qq_48051316/article/details/127929257