• 浏览器自动化


    什么是 selenium

    selenium 是浏览器自动化测试框架,原本被用于网页测试。但到了爬虫领域,它又成为了爬虫的好帮手。selenium 可以控制你的浏览器,模仿人浏览网页,从而获取数据,自动操作等。一图胜千言

    安装 selenium

    和其他 Python 第三方库的安装一样,我们要在命令行中使用 pip 命令安装 selenium:

    1 pip install selenium -i https://pypi.doubanio.com/simple

    selenium 还需要安装相应的浏览器驱动才能控制浏览器

    chromedriver驱动下载网站:

    https://registry.npmmirror.com/binary.html?path=chromedriver/

    将下载好的 chromedriver 解压缩,Windows 系统得到 chromedriver.exe,MacOS 得到 chromedriver,这个就是我们需要的浏览器驱动。我们要将它放到 Python 所在安装目录里。 如果你忘了 Python 的安装目录,可以根据下面的操作来找到。

    1 import sys
    2 print(sys.executable)

     打开浏览器:

    from selenium import webdriver
    
    browser = webdriver.Chrome()
    # 打开网页
    browser.get('https://wpblog.x0y1.com')
    # 关闭浏览器
    browser.quit()

    browser 是我们实例化的浏览器。我们将网址传给 browser 对象的 get() 方法,即可打开对应的网页。最后调用 quit() 方法将浏览器关闭。

    我们的目的是获取数据,接下来让我们用 browser 对象的 page_source 属性来获取网页的源代码。值得注意的是,用 selenium 获取的网页源代码是数据加载完毕后最终的源代码,也就是网页加载后通过 API 获取的数据也在这个源代码中。

    因此,我们就不用再区分要爬取的网页是静态网页还是动态网页了,在 selenium 眼里统统都一样

    用 selenium 打印出博客的网页源代码:

    from selenium import webdriver
    
    browser = webdriver.Chrome()
    browser.get('https://wpblog.x0y1.com')
    # 打印出网页源代码
    print(browser.page_source)
    browser.quit()

    处理数据

    我们之前掌握了用 BeautifulSoup 对获取的网页源代码进行处理,提取出我们需要的内容。selenium 也同样可以进行数据的处理,它俩原理类似,只是语法上有所不同。

    接下来,我们来看看如何用 selenium 处理数据。我们以获取博客的 h1 标签为例,代码可以这样写:

    from selenium import webdriver
    
    browser = webdriver.Chrome()
    browser.get('https://wpblog.x0y1.com')
    h1 = browser.find_element_by_tag_name('h1')
    print(h1.text)
    browser.quit()

    Selenium常用的查找元素的方法:

     我们来看几个例子你就明白了,下面的例子中,注释内容是要找的 HTML 元素代码,下面是获取该元素的 Python 代码:

     1 # <p>扇贝编程,带你打开编程世界的大门</p>
     2 browser.find_element_by_tag_name('p')
     3 
     4 # <p class="slogan">扇贝编程,带你打开编程世界的大门</p>
     5 browser.find_element_by_class_name('slogan')
     6 
     7 # <p id="slogan">扇贝编程,带你打开编程世界的大门</p>
     8 browser.find_element_by_id('slogan')
     9 
    10 # <p name="slogan">扇贝编程,带你打开编程世界的大门</p>
    11 browser.find_element_by_name('slogan')
    12 
    13 # <a href="http://code.shanbay.com">扇贝编程</a>
    14 browser.find_element_by_link_text('扇贝编程')
    15 browser.find_element_by_partial_link_text('扇贝')

     selenium 新增了一种更统一的方法 find_element(),而具体通过什么来查找(tag name, class name 等)放进了参数中。

     1 # <p>扇贝编程,带你打开编程世界的大门</p>
     2 browser.find_element('tag name', 'p')
     3 
     4 # <p class="slogan">扇贝编程,带你打开编程世界的大门</p>
     5 browser.find_element('class name', 'slogan')
     6 
     7 # <p id="slogan">扇贝编程,带你打开编程世界的大门</p>
     8 browser.find_element('id', 'slogan')
     9 
    10 # <p name="slogan">扇贝编程,带你打开编程世界的大门</p>
    11 browser.find_element('name', 'slogan')
    12 
    13 # <a href="http://code.shanbay.com">扇贝编程</a>
    14 browser.find_element('link text', '扇贝编程')
    15 browser.find_element('partial link text', '扇贝')
    与上面例子对比

     

    这些方法找到的元素(返回值)都是 WebElement 对象,它和 BeautifulSoup 里的 Tag 对象一样,也有一个 text 属性,一样也是获取元素里的文本内容。

    不同的是,Tag 对象通过字典取值的方式获取元素的属性值,而 WebElement 对象则使用 get_attribute() 方法来获取。

     我们来看个代码实例加深一下印象:

    # <a href="http://code.shanbay.com">扇贝编程</a>
    link = browser.find_element_by_link_text('扇贝编程')
    print(link.get_attribute('href'))
    # 输出:http://code.shanbay.com
    print(link.text)
    # 输出:扇贝编程

       如果想要查找所有符合条件的元素 只要把刚才介绍的那些方法名中的 element 改成 elements 即可

     1 from selenium import webdriver
     2 
     3 browser = webdriver.Chrome()
     4 browser.get('https://wpblog.x0y1.com')
     5 # 注意下面是 elements
     6 a_tags = browser.find_elements_by_tag_name('a')
     7 # 新版本写法:
     8 # a_tags = browser.find_elements('tag name', 'a')
     9 
    10 for tag in a_tags:
    11   print(tag.text)
    12 browser.quit()
    获取源代码中所有的a标签

     

    控制浏览器

    还记得我们上一关说的,登录博客并批量获取博客中的文章内容吗?我们可以使用 selenium 进行同样的操作,代码的可读性更强,我们写起来也更轻松。

    要想做到这些,除了刚才学的那些查找元素的方法外,只要再学两个方法即可。这两个方法分别是 click() 和 send_keys(),我们来看看它俩的作用:

    自动登录博客并获取文章内容的代码如下,请仔细阅读注释内容:

    提示:我们在下面的代码还用了一对新的查找元素的方法:find_element_by_css_selector() 和 find_elements_by_css_selector() ,这就运用了上一课所说的 css 选择器的知识,将 css 选择器以字符串的形式填入括号中,能帮我们更精准地查找元素。

    from selenium import webdriver
    import time
    
    browser = webdriver.Chrome()
    # 打开博客
    browser.get('https://wpblog.x0y1.com')
    # 找到登录按钮
    login_btn = browser.find_element_by_link_text('登录')
    # 点击登录按钮
    login_btn.click()
    # 等待 2 秒钟,等页面加载完毕
    time.sleep(2)
    # 找到用户名输入框
    user_login = browser.find_element_by_id('user_login')
    # 输入用户名
    user_login.send_keys('codetime')
    # 找到密码输入框
    user_pass = browser.find_element_by_id('user_pass')
    # 输入密码
    user_pass.send_keys('shanbay520')
    # 找到登录按钮
    wp_submit = browser.find_element_by_id('wp-submit')
    # 点击登录按钮
    wp_submit.click()
    # 找到 Python 分类文章链接
    python_cat = browser.find_element_by_css_selector('section#categories-2 ul li a')
    # 上一句用新版本的写法如下
    # python_cat = browser.find_element('css selector', 'section#categories-2 ul li a')
    # 点击该分类
    python_cat.click()
    # 找到跳转的页面中的所有文章标题标签
    titles = browser.find_elements_by_css_selector('h2.entry-title a')
    # 上一句用新版本的写法如下
    # titles = browser.find_elements('css selector', 'h2.entry-title a')
    
    # 找到标题标签中内含的链接
    links = [i.get_attribute('href') for i in titles]
    # 依次打开 links 中的文章链接
    for link in links:
      browser.get(link)
      # 获取文章正文内容
      content = browser.find_element_by_class_name('entry-content')
      print(content.text)
      
    browser.quit()
    获取文章内容

    复习与总结

    •  我们是从安装浏览器驱动开始的,为了能让 selenium 控制浏览器,驱动是必需的。

          驱动安装完成后,我们迫不及待地用代码控制打开了浏览器,代码是这样的:

      
    1 # 从 selenium 中导入 webdriver(驱动)
    2 from selenium import webdriver
    3 
    4 # 选择 Chrome 浏览器并打开
    5 browser = webdriver.Chrome()
    打开浏览器
    • 接着我们调用实例化后的浏览器对象(browser)的 get() 方法成功地打开了一个网页,并且通过其 page_source 属性拿到了网页的源代码。注意,最后一定要调用 quit() 方法将浏览器关闭。
      • 1 from selenium import webdriver
        2 
        3 browser = webdriver.Chrome()
        4 browser.get('https://wpblog.x0y1.com')
        5 # 打印出网页源代码
        6 print(browser.page_source)
        7 # 关闭浏览器
        8 browser.quit()
        打开网页 
    • 有些网站数据较多,网页加载比较慢,打开网页后需要暂停几秒才能获取到完整的网页源代码。以上代码可以总结成下图:
    • 光拿到网页源代码还不够,我们还要解析、处理它,从中提取出我们需要的数据。selenium 中解析与提取数据的方法如下:
      •  上面是获取第一个符合条件的元素的方法,获取所有符合条件的元素的方法只需把 element 改成 elements 即可:

    • 这些方法找到的元素(返回值)都是 WebElement 对象,它的常用属性和方法如下:’
    • 举个获取 a 标签中链接和内容的例子:
      • 1 # <a href="http://code.shanbay.com">扇贝编程</a>
        2 link = browser.find_element_by_link_text('扇贝编程')
        3 print(link.get_attribute('href'))
        4 # 输出:http://code.shanbay.com
        5 print(link.text)
        6 # 输出:扇贝编程
        获取a标签
    • 接着我们学会了将 selenium 与 BeautifulSoup 相结合,用 selenium 获取网页源代码,用 BeautifulSoup 解析、提取数据。
      •  1 from selenium import webdriver
         2 from bs4 import BeautifulSoup
         3 
         4 browser = webdriver.Chrome()
         5 browser.get('https://wpblog.x0y1.com')
         6 # 用 BeautifulSoup 解析网页源代码
         7 soup = BeautifulSoup(browser.page_source, 'html.parser')
         8 a_tags = soup.find_all('a')
         9 for tag in a_tags:
        10   print(tag.text)
        11 browser.quit()
        selenium与BeautifulSoup结合
    • 最后,我们还学习了 selenium 中操作浏览器的方法,
    • 通过 selenium 查找元素的方法找到对应的元素后,调用其 click() 方法就可以模拟点击该元素,一般用于点击链接或按钮;调用其 send_keys() 方法用于模拟按键输入,传入要输入的内容即可,常用于账号密码等输入框的表单填写。
    • selenium简单明了,使用起来非常的直观,和我们正常使用浏览器的步骤一样,不需要分析浏览器背后发生的逻辑。

      但它的缺点也很明显,因为 selenium 需要真实的打开浏览器,等待网页加载等。在大规模获取数据时,使用 selenium 爬取数据将会非常的低效。

      为了提升爬取效率,我们可以将浏览器设置为静默模式,让浏览器不必真的打开,而是在后台默默地获取数据、操作页面。代码如下:

       1 from selenium import webdriver
       2 
       3 # 初始化配置
       4 options = webdriver.ChromeOptions()
       5 # headless 为静默模式
       6 options.add_argument('--headless')
       7 # 将配置传入浏览器
       8 browser = webdriver.Chrome(options=options)
       9 # 打开网页
      10 browser.get('https://wpblog.x0y1.com')
      11 # 关闭浏览器
      12 browser.quit()
      设置静默模式

      即使我们将浏览器配置成静默模式,在大规模爬取数据,selenium 的爬取速度和资源占用率都不太理想。所以,通常情况下,我们还是会用 requests 和 BeautifulSoup 爬取数据

  • 相关阅读:
    oauth
    web api Authorization
    sql 找到前三
    js计算误差修正代码(真实版)
    js操作keyframes动态赋值
    元素拖拽缩放的jquery插件
    js生成组织结构树(原创)
    js图片拖拽、缩放、添加图层功能(原创)
    for循环,forin循环和Array.every(),obj.forEach()方法运行速度对比
    for循环+forin循环生成内容模版
  • 原文地址:https://www.cnblogs.com/Vowzhou/p/15990316.html
Copyright © 2020-2023  润新知