利用Selenium 可以驱动浏览器执行特定的动作,如点击、下拉等操作, 同时还可以获取浏览器当前呈现的页面的源代码 ,做到可见即可爬。

  1. 基本使用
  • 示例:

    from selenium importwebdriverfrom selenium.webdriver.common.by importByfrom selenium.webdriver.common.keys importKeysfrom selenium.webdriver.support importexpected_conditions as ECfrom selenium.webdriver.support.wait importWebDriverWait
    browser=webdriver.Chrome()try:browser.get('https://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')))print(browser.current_url)print(browser.get_cookies())print(browser.page_source)finally:browser.close()

    运行代码后,会自动弹出一个 Chrome 浏览器。首先会跳转到百度,然后在搜索框中输入 Python,接着跳转到搜索页。  搜索结果加载出来后,控制台分别会输出当前的 URL 、当前的 Cookies 和网页源代码.

  • 如果用 Selenium 来驱动浏览器加载网页的话,就可以直接拿到 JavaScript 渲染的结果,不用担心使用的是什么加密系统。声明浏览器对象  

声明浏览器对象

  • Selenium 支持非常多浏览器,如 Chrome/ Firefox/ Edge等,还有 Android 等手机端的浏览器,也支持无界面浏览器 PhantomJS。

    • 初始化方式:

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

      浏览器对象的初始化并将其赋值为 browser对象。接下来,就是调用 browser 对象,让其执行各个动作以模拟浏览器操作

访问页面

  • 用 get()方法来请求网页,参数传入链接 URL 即可。如用 get()方法访问淘宝, 然后输出源代码,代码:

    from selenium importwebdriver
    browser=webdriver.Chrome()
    browser.get('https://www.taobao.com/')print(browser.page_source)

    弹出了 Chrome 浏览器并且自动访问了淘宝,然后控制台输出了淘宝页面的源代码, 随后浏览器关闭。可以实现浏览器的驱动并获取网页源码

查找节点

  • Selenium 可以驱动浏览器完成各种操作,如填充表单、模拟点击等。Selenium 提供了系列查找节点的方法,我们可以用这些方法来获取想要的节点,以便执行一些动作或者提取信息。
  1. 单个节点

    • 如,要从淘宝页面中提取搜索框这个节点,观察源代码(它的 id 是 q, name 也是q。此时就可以用多种方式获取它。如,find_element_by_name()是根据 name 值获取,find element_by_id()是根据 id 获取。 还有根据 XPath、css 选择器等获取的方式):

      from selenium importwebdriver
      browser=webdriver.Chrome()
      browser.get('https://www.taobao.com')
      input_first= browser.find_element_by_id('q')
      input_second= browser.find_element_by_xpath('//*[@id ="q"]')
      input_third= browser.find_element_by_css_selector('#q')print(input_first, input_second, input_third)
      browser.close()

      这里使用 3 种方式获取输入框,分别根据 ID, CSS 选择器和 XPath 获取,它们返回的结果完全一致。

    • 列出所有获取单个节点的方法:
      • find_element_by_id
      • find_element_by_name
      • find_element_by_xpath
      • find_element_by_link_text
      • find_element_by_partial_link_text
      • find_element_by_tag_name
      • find_element_by_class_name
      • find_element_by_css_selector
    • Selenium 提供了通用方法 find_element (),需要传入两个参数:查找方式 By 和值。就是 find_element_by_id()这种方法的通用函数版本,如 find_element_by_id(id )等价 find_element(By.ID, id),得到的结果完全一致。代码:
      from selenium importwebdriverfrom selenium.webdriver.common.by importBybrowser=webdriver.Chrome()
      browser.get('https://www.taobao.com')
      input_first= browser.find_element(By.ID, 'q')print(input_first)
      browser.close()

      查找方式的功能与上面列举函数一致,参数更加灵活。

  2. 多个节点
    • 如果有多个节点,用 find_element()方法查找,就只能得到第一个节点。如果要查找所有满足条件的节点, 需要用 find_elements()方法。注意,这个方法名称中,element 多了一个s 

      • 查找淘宝侧边导航条的所有条目:

        from selenium importwebdriver
        browser=webdriver.Chrome()
        browser.get('https://www.taobao.com')
        lis= browser.find_elements_by_css_selector('.service-bd li')print(lis)
        browser.close()

        得到的内容变成了列表类型,列表中的每个节点都是 WebElement 类型。

        如果用 find_element()方法,只能获取匹配的第一个节点,结果是 WebElement类型。如果用 find_elements()方法,结果是列表类型,列表中的每个节点是 WebElement 类型。

        • 列出所有获取多个节点的方法:
        • find_elements_by_id
        • find_elements_by_name
        • find_elements_by_xpath
        • find_elements_by_link_text
        • find_elements_by_tag_name
        • find_elements_by_class_name
        • find_elements_by_css_selector

        也可以直接用 find_elements()方法来选择,可以这样写,结果是完全一致的:

        • lis = browser.find_elements(By.CSS_SELECTOR, ’.service-bd li')  

节点互交

  • Selenium 可以让浏览器模拟执行一些动作。常见的用法有:输入文字时用 send_keys()方法,清空文字时用 clear()方法,点击按钮时用 click()方法。示例:

    from selenium importwebdriverimporttime
    browser=webdriver.Chrome()
    browser.get('https://www.taobao.com')
    input= browser.find_element_by_id('q')
    input.send_keys('iPhone')
    time.sleep(1)
    input.clear()
    input.send_keys('iPad')
    button= browser.find_element_by_class_name('btn-search')
    button.click()

    首先驱动浏览器打开淘宝,用 find_element_by_id()方法获取输入框,再用 send_keys() 方法输入 iPhone 文字,等待秒后用 clear()方法清空输入框,再次调用 send_keys()方法输入 iPad 文字,之后再 find_element_by_class_name()方法获取搜索按钮,最后调用 click ()方法完成搜索动作。

  • 更多的操作参见官方文档交互动作介绍:http://selenium-python.readthedocs.io/api.html#module-selenium.webdriver.remote.webelement。

动作链

  • 动作链 没有特定的执行对象,如:鼠标拖曳、键盘按键等。
  • 如:现在实现一个节点的拖曳操作,将某个节点从一处拖曳到另外一处,实现代码:
    from selenium importwebdriverfrom selenium.webdriver importActionChainsbrowser=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.perform

    打开网页中一个拖曳实例,依次选中要拖曳的节点和拖曳到的目标节点,接着声明 ActionChains 对象并将其赋值为 actions 变量,然后调用 actions 变量的 drag_and_drop()方法,再调 perform()方法执行动作。

  • 更多动作链操作 官方文档:http://selenium-python.readthedocs.io/api.html#moduleselenium.webdriver.common.action_chains

执行JavaScript

  • 某些操作,Selenium API 并没有提供。如,下拉进度条,它可以直接模拟运行 JavaScript,此时使用 execute_script()方法即可实现,(注意:execute_script)

    from selenium importwebdriverbrowser=webdriver.Chrome()
    browser.get('https://www.zhihu.com/explore')
    browser.execute_script('window.scrollTo(0,document.body.scrollHeight)')
    browser.execute_script('alert("To Bottom")')

获取节点信息

  • 通过 page_source 属性可以获取网页的源代码,接着使用解析库(如正则表式、Beautiful Soup、pyquery 等)提取信息。
  • 获取属性
    • 可以使用 get_attribute ()方法来获取节点的属性,但是其前提是先选中这个节点,示例:

      from selenium importwebdriver
      browser=webdriver.Chrome()
      url= 'https://zhihu.com/explore'browser.get(url)
      logo= browser.find_element_by_id('zh-top-link-logo')print(logo)print(logo.get_attribute('class'))

      结果获取知乎的 logo 节点,最后打印出它的 class。

      通过 get_attribute()方法,然后传人想要获取的属性名,就可以得到它的值了

  • 获取文本值
    • 每个 WebElement 节点都有 text 属性,直接调用这个属性就可以得到节点内部的文本信息,相当于 Beautiful Soup 的 get_text()方法、 pyquery 的 text()方法。示例:

      from selenium importwebdriver
      browser=webdriver.Chrome()
      url= 'https://www.zhihu.com/explore'browser.get(url)
      input= browser.find_element_by_class_name('zu-top-add-question')print(input.text)

  • 获取id、位置、标签名和大小
    • Web Element 节点还有 些其他属性,如 id 属性可以获取节点 id,location 属性可以获取该节点在页面中的相对位置,tag_name 属性可以获取标签名称,size 属性可以获取节点的大小(宽高),示例:

      from selenium importwebdriver
      browser=webdriver.Chrome()
      url= 'https://www.zhihu.com/explore'browser.get(url)
      input= browser.find_element_by_class_name('zu-top-add-question')print(input.text)print(input.id)print(input.location)print(input.size)print(input.tag_name)

      首先获得“提问”按钮节点,再调用其 id、location、tag_name、size 属性来获取对应的属性值

切换Frame

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

    importtimefrom selenium importwebdriverfrom selenium.common.exceptions importNoSuchElementException
    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= browser.find_element_by_class_name('logo')exceptNoSuchElementException:print('NO LOGO')
    browser.switch_to.parent_frame()
    logo= browser.find_element_by_class_name('logo')print(logo)print(logo.text)

    以前面动作链操作的网页例,首先通过 switch_to.frame()方法切换到子 Frame 里,再尝试获取父级 Frame 里的 logo 节点(这是不能找到的),如果找不到的话,就会抛出 NoSuchEle entException 异常,异常被捕捉之后,就会输出 NO LOGO。接下来,重新切换父级 Frame, 然后再次重新获取节点,发现此时可以成功获取了。

    当页面中包含子 Frame 时,如果想获取子 Frame 中的节点,需要先调用 switch_to.frame() 方法切换到对应的 Frame,再进行操作。  

延时等待

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

    • 延时等待方式有两种:隐式等待和显式等待
  • 隐式等待
    • 使用隐式等待执行测试的时候,如果 Selenium 没有在 DOM 中找到节点,将继续等待,超出设定时间后(默认时间为 0 ),则抛出找不到节点的异常。示例:

      from selenium importwebdriver
      browser=webdriver.Chrome()
      browser.implicitly_wait(10)
      browser.get('https://www.zhihu.com/explore')
      input= browser.find_element_by_class_name('zu-top-add-question')print(input)

      用 implicitly_wait()方法实现隐式等待。

  • 显式等待
    • 指定要查找的节点,然后指定一个最长等待时间。如果在规定时间内加载出来了这个节点,就返回查找的节点;如果到了规定时间依然没有加载出该节点, 则抛出超时异常。示例:

      from selenium importwebdriverfrom selenium.webdriver.common.by importByfrom selenium.webdriver.support.ui importWebDriverWaitfrom selenium.webdriver.support importexpected_conditions as ECbrowser=webdriver.Chrome()
      browser.get('https://www.taobao.com/')
      wait= WebDriverWait(browser,10)
      input= wait.until(EC.presence_of_element_located((By.ID, 'q')))
      button= wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, '.btn-search')))print(input, button)

      首先引人 WebDriverWait 对象,指定最长等待时间,调用 until()方法,传人要等待条件 expected_conditions。如:传入 presence_of_element_located 条件,代表节点出出现意思,参数是节点的定位元组,也就是 ID 为 q 的节点搜索框

      效果:在 10 秒内如果 ID 为 q的节点(搜索框)成功加载出来,就返回该节点;如果超过 10 秒还没有加载出来,就抛出异常。

      • 对于按钮,更改一下等待条件,如改为 element_to_be_clickable,也就是可点击,所以找按钮时查找 CSS 选择器为 .btn_search 的按钮,如果 10 秒内它是可点击的,也就是成功加载,返回这个按钮节点;如果超过 10 秒还不可点击,就抛出异常.

        • 等待条件,如判断标题内容,判断某个节点内是否出现了某文字。等待条件:
        • title_is:标题是某内容
        • title_contains: 标题包含某内容
        • presence_of_element_located:节点加载出来,传入定位元组,如(By.ID,‘q’)
        • visibility_of_element_located:节点课件,传入定位元组
        • visibility_of:可见,传入节点对象
        • presence_of_all_elements_ilocated:所有节点加载出来
        • text_to_be_present_in_element:某个节点文本包含某文字
        • text_to_be_present_in_element_value:某个节点值包含某文字
        • frame_to_be_available_and_switch_to_it:加载并切换
        • invisibility_of_element_located:节点不可见
        • element_to_be_clickable:节点可点击
        • staleness_of:判断一个节点是否仍在DOM,可判断页面是否已经刷新
        • element_to_be_selected:节点可选择,传节点对象
        • element_located_to_be_selected:节点可选择,传入定位元组
        • element_election_state_to_be:传入节点对象以及状态,相等返回True,否则返回False
        • element_located_selection_state_to_be:传入定位元组。以及状态,相等返回True,否则返回False
        • alert_is_present:是否出现警告
      • 更多等待条件的参数及用法,参考官方文档: http://selenium-python.readthedocs.io/api.html#module-selenium.webdriver.support.expected_conditions。

前进和后退

  • Selenium 可以完成前进和后退操作,它使用 back()方法后退,使用 forward()方法前进。示例:

    importtimefrom selenium importwebdriverbrowser=webdriver.Chrome()
    browser.get('https://www.baidu.com/')
    browser.get('https://www.taobao.com/')
    browser.get('https://www.python.org/')
    browser.back()
    time.sleep(1)
    browser.forward()
    browser.close()

    连续访问3个页面,调用 back()方法回到第二个页面,再调用 forward()方法前进到第 3个页面。

Cookies

  • Selenium 可以方便地对 Cookies 进行 获取、添加、删除等。示例:

    from selenium importwebdriverbrowser=webdriver.Chrome()
    browser.get('https://www.zhihu.com/explore')print(browser.get_cookies())
    browser.add_cookie({'name': 'name', 'domain': 'www.zhihu.com', 'value': 'germey'})print(browser.get_cookies())
    browser.delete_all_cookies()print(browser.get_cookies())

    访问知乎,加载完成后,浏览器已经生成 Cookies。调用 get_cookies() 方法获取所有的 Cookies。然后,添加一个 Cookie,传入一个字典,有name、domain、value内容。再次获取所有 Cookies。结果就多了新加的 Cookie。调用 delete_all_cookies()方法删除所有 Cookies。再重新获取,结果就为空了。

选项卡管理

  • 访问网页时候,会开启一个个选项卡。Selenium 中,也可以对选项卡进行操作。示例:

    importtimefrom selenium importwebdriverbrowser=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.taobap.com')
    time.sleep(1)
    browser.switch_to_window(browser.window_handles[0])
    browser.get('https://python.org')

    首先访问百度,然后调用 execute_script()方法,传入 window.open()这个 JavaScript 语句新开启一个选项卡。接下来,想切换到该选项卡,调用 window_handles 属性获取当前开启的所有选项卡,返回的是选项卡的代号列表。要想切换选项卡,只需要调用 switch_to_window()方法即可,其中参数是选项卡的代号。将第二个选项卡代号传人,即跳转到第二个选项卡,接下来在第二个选项卡下打开一个新页面,然后切换回第一个选项卡重新调用 switch_to_window()方法,再执行其他操作。

异常处理

  • 在使用 Selenium 过程中,可以使用 try except 语句来捕获各种异常。(模拟节点未找到异常)示例:

    from selenium importwebdriver
    browser=webdriver.Chrome()
    browser.get('https://www.baidu.com')
    browser.find_element_by_id('hello')

    首先打开百度页面,尝试选择一个并不存在的节点 ,此时就会遇到异常。捕获异常示例:

    from selenium importwebdriverfrom selenium.common.exceptions importTimeoutException, NoSuchElementExceptionbrowser=webdriver.Chrome()try:browser.get('https://www.baidu.com')exceptTimeoutException:print('Timeout')try:browser.find_element_by_id('hello')exceptNoSuchElementException:print('No Element')finally:browser.close()

    这里使用 try except 来捕获各类异常。如,对 find_element_by_id()查找节点方法捕获 NoSuchElementException 异常,一旦出现这样的错误,就进行异常处理,程序也不会中断。

  • 更多异常类,参考官方文档 http://selenium-python.readthedocs.io/api.html#module-selenium.common.exceptions。

转载于:https://www.cnblogs.com/Mack-Yang/p/10184662.html

Class 17 - 1 动态渲染页面爬取 — Selenium使用相关推荐

  1. scrapy模拟浏览器爬取51job(动态渲染页面爬取)

    scrapy模拟浏览器爬取51job 51job链接 网络爬虫时,网页不止有静态页面还有动态页面,动态页面主要由JavaScript动态渲染,网络爬虫经常遇见爬取JavaScript动态渲染的页面. ...

  2. JavaScript 动态渲染页面爬取(二) —— 基于 Splash

    目录 一.安装 Splash 二.Splash 的使用 一.安装 Splash Splash 是一个 JavaScript 渲染服务,是一个含有 HTTP API 的轻量级浏览器,它还对接了 Pyth ...

  3. Selenium解决动态渲染页面----爬取网易云音乐全部评论

    爬取网易云音乐全部评论,我们先随便找一首歌,这里以毛不易的水乡为例.毛不易–水乡 一.常规方法 1. 尝试直接爬取 先直接用歌曲链接直接爬取 import requests#URL url = 'ht ...

  4. JavaScript 动态渲染页面爬取(一) —— 基于 Selenium

    目录 一.安装 Selenium 二.Selenium 的使用 一.安装 Selenium 利用 Ajax 接口 爬取数据的方法通常有两种: 一种是深挖其中的逻辑,把请求需要的参数的构造逻辑完全找出来 ...

  5. 第46讲:遇到动态页面怎么办?详解渲染页面爬取

    前面我们已经介绍了 Scrapy 的一些常见用法,包括服务端渲染页面的抓取和 API 的抓取,Scrapy 发起 Request 之后,返回的 Response 里面就包含了想要的结果. 但是现在越来 ...

  6. Python3网络爬虫实战-38、动态渲染页面抓取:Splash的使用

    Splash 是一个 JavaScript 渲染服务,是一个带有 HTTP API 的轻量级浏览器,同时它对接了 Python 中的 Twisted和 QT 库,利用它我们同样可以实现动态渲染页面的抓 ...

  7. 爬虫:动态页面爬取Selenium

    Ajax其实也是JavaScript动态渲染的页面的一种情形,不过JavaScript 动态渲染的页面不止Ajax 这一种: 比如中国青年网(详见 http://news.youth.cn/gn/ ) ...

  8. 爬虫——动态渲染页面抓取

    文章目录 Selenium的使用 Chrome浏览器配置ChromeDriver 声明浏览器对象,初始化 访问页面 节点查找 多个节点 节点交互,操作 动作链,拖拽,按钮 执行JavaScript,进 ...

  9. [Python3网络爬虫开发实战] 7-动态渲染页面爬取-4-使用Selenium爬取淘宝商品

    在前一章中,我们已经成功尝试分析Ajax来抓取相关数据,但是并不是所有页面都可以通过分析Ajax来完成抓取.比如,淘宝,它的整个页面数据确实也是通过Ajax获取的,但是这些Ajax接口参数比较复杂,可 ...

最新文章

  1. 湖南科技大学c语言程序设计b,2017年湖南科技大学计算机科学与工程学院826C语言程序设计与数据结构综合之数据结构考研题库...
  2. C++中自定义比较函数和重载运算符总结
  3. Windows上部署Ngnix
  4. pip list和pip freeze的区别(列出所有包,列出包的requirements格式)
  5. 细说ASP.NET Core与OWIN的关系
  6. pythonqueue线程_python之线程queue
  7. 库克宣布苹果将捐款帮助山西
  8. mac系统postman+newman生成测试报告
  9. max点缓存烘焙帧_3DMAX怎么进行点缓存?
  10. 2:0战胜Dota2世界冠军OG,OpenAI发起全网挑战,不服来战!
  11. Docker概述(一)(标贝科技)
  12. 《Python编程快速上手——让繁琐的工作自动化》读书笔记2
  13. FPS游戏:D3D实现游戏人物上色
  14. 【历史上的今天】12 月 16 日:晶体管问世;IBM 停售 OS/2;科幻小说巨匠诞生
  15. mysql inet aton ipv6_mysql 使用inet_aton和inet_ntoa处理ip地址数据
  16. 刚子扯谈:要明白网站建设的真正意义
  17. AcWing 125. 耍杂技的牛 (推公式)
  18. 前端面试题第二次整理(第二次找工作)
  19. sncr脱硝技术流程图_SNCR脱硝工艺介绍.ppt
  20. 什么是防火墙?防火墙能发挥什么样的作用?

热门文章

  1. 关闭sql执行功能及找回08CMS系统管理员密码
  2. andiod 导入工程 报错
  3. soap header身份认证 不带ns标签
  4. Linux中设置ip
  5. 谈谈 Cookie 存取和IE页面缓存的问题
  6. 100个LINUX站点
  7. 应用Rational 工具简化基于J2EE的项目(二)启动项目
  8. pain point
  9. MET 3P5: 工业工程
  10. subprime debt