浏览器自动化

什么是 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 爬取数据

 

 

posted @ 2022-03-15 17:34  Vowzhou  阅读(912)  评论(0编辑  收藏  举报