一、前言
在前文中,我们详细介绍了 BeautifulSoup 这一工具。在处理静态数据爬取任务时,它确实展现出了快捷、方便的特性,能够高效地完成相关工作。然而,当前市面上诸多规范运营的网站,为了保障自身数据安全与运营秩序,纷纷采取了一系列反爬虫措施。
这些措施不仅涵盖了懒加载技术,使得页面数据不会一次性全部加载,增加爬取难度;部分网站还设置了登录认证拦截,只有通过特定身份验证的用户才能访问数据。在此情形下,BeautifulSoup 的局限性便暴露无遗,面对这些复杂的反爬虫机制,它往往显得力不从心。
那么,该如何突破这些阻碍,实现对数据的有效爬取呢?此时,我们不得不引入另一种功能强大的数据爬取工具 ——Selenium。它将为我们在应对复杂反爬虫场景时,开辟出一条全新的路径 。
二、动态网页的征服者——Selenium介绍
2.1.Selenium是什么?
原则上Selenium 是一个自动化测试工具,这个对于玩自动化测试的同学应该特别熟悉。同时也能很好地应用在爬虫领域。
它就像一个虚拟的浏览器,可以模拟用户在浏览器里的各种操作,比如点击按钮、滚动页面、输入文字等等。通过控制真实的浏览器(像 Chrome、Firefox),Selenium 能获取到完整的网页内容,包括那些需要加载才能显示的部分。
所以在动态爬取数据上,这个万一就很方便了,因此咱们直接用它来爬取一个动漫全集试试。因为是找百度上的动漫网站,但是其中的内容可能有些是一些特定平台的付费内容,所以
特此说明:
这里只提是供学习方法参考,而不涉及商用或者兜售传播之类的东西哈!!!
2.2.Selenium在Python爬虫中的常见函数介绍
2.2.1.初始化浏览器驱动
在使用 Selenium 开展网页爬取工作之前,初始化浏览器驱动是必不可少的前置步骤。浏览器驱动作为 Selenium 与浏览器之间沟通的桥梁,能够让我们通过代码控制浏览器的行为。
常见的浏览器驱动有 ChromeDriver、FirefoxDriver 等。不同的浏览器需要对应的驱动程序,并且驱动的版本要与浏览器版本相匹配,否则可能会出现兼容性问题,导致无法正常启动浏览器。
python">from selenium import webdriver# 设置 ChromeDriver 的路径
driver_path = 'path/to/chromedriver'
# 创建 Chrome 浏览器驱动实例
driver = webdriver.Chrome(executable_path=driver_path)
为了避免每次都手动指定驱动路径,可以将驱动所在目录添加到系统的环境变量中,这样在代码中就可以直接使用 webdriver.Chrome()
来创建驱动实例,无需再指定 executable_path
参数。
2.2.2 打开网页
使用 get()
方法可以打开指定的网页。这是一个非常基础且常用的操作,通过该方法可以让浏览器访问指定的 URL 地址。
python"># 打开指定网页
driver.get('https://www.example.com')
当执行 get()
方法时,浏览器会尝试加载指定的网页,直到页面加载完成或者达到超时时间。
但是在实际应用中,有些网页可能加载速度较慢,为了避免因页面未完全加载而导致后续操作失败,可以结合等待机制来确保页面加载完成后再进行下一步操作。
2.2.3 查找元素
Selenium 提供了多种查找元素的方法,这些方法可以根据元素的不同属性来定位元素。
通过 ID 查找元素
使用 find_element_by_id()
方法可以通过元素的 ID 属性查找元素。ID 属性在一个 HTML 页面中是唯一的,因此通过 ID 查找元素是一种非常高效且准确的方式。
python"># 查找 ID 为 'element_id' 的元素
element = driver.find_element_by_id('element_id')
在查找元素时,如果元素的 ID 是动态生成的,那么就不能直接使用这种方法。此时可以考虑结合其他属性或者使用 XPath 来定位元素。
通过类名查找元素
使用 find_element_by_class_name()
方法可以通过元素的类名查找元素。类名通常用于给一组具有相同样式的元素添加样式,因此一个页面中可能会有多个元素具有相同的类名。
python"># 查找类名为 'element_class' 的元素
element = driver.find_element_by_class_name('element_class')
当一个页面中有多个元素具有相同的类名时,该方法只会返回第一个匹配的元素。如果需要查找所有匹配的元素,可以使用 find_elements_by_class_name()
方法。
通过标签名查找元素
使用 find_element_by_tag_name()
方法可以通过元素的标签名查找元素。HTML 页面中有很多不同类型的标签,如 div
、p
、a
等。
python"># 查找标签名为 'div' 的元素
element = driver.find_element_by_tag_name('div')
同样,该方法只会返回第一个匹配的元素。如果需要查找所有匹配的元素,可以使用 find_elements_by_tag_name()
方法。而且,由于一个页面中可能会有大量相同标签名的元素,使用这种方法定位元素时可能会不够准确,需要结合其他方法进行筛选。
通过 CSS 选择器查找元素
使用 find_element_by_css_selector()
方法可以通过 CSS 选择器查找元素。CSS 选择器是一种强大的元素定位工具,可以根据元素的标签名、类名、ID 等属性组合来定位元素。
python"># 查找 CSS 选择器为 'div.class_name' 的元素
element = driver.find_element_by_css_selector('div.class_name')
CSS 选择器的语法非常灵活,可以通过组合不同的属性来实现更精确的元素定位。例如,可以使用 #element_id
来定位具有特定 ID 的元素,使用 .class_name
来定位具有特定类名的元素。
通过 XPath 查找元素
使用 find_element_by_xpath()
方法可以通过 XPath 表达式查找元素。XPath 是一种用于在 XML 文档中定位节点的语言,在 HTML 页面中也可以使用 XPath 来定位元素。
python"># 查找 XPath 为 '//div[@id="element_id"]' 的元素
element = driver.find_element_by_xpath('//div[@id="element_id"]')
XPath 可以根据元素的属性、位置等信息进行非常精确的元素定位。但是,XPath 表达式的编写相对复杂,需要对 HTML 结构有一定的了解。在编写 XPath 表达式时,可以使用浏览器的开发者工具来辅助生成。
2.2.4 操作元素
找元素后,可以对其进行各种操作,常见的操作有以下几种:
输入文本
使用 send_keys()
方法可以向输入框中输入文本。这在模拟用户在表单中输入信息时非常有用。
python"># 查找 ID 为 'input_id' 的输入框元素
input_element = driver.find_element_by_id('input_id')
# 向输入框中输入文本
input_element.send_keys('Hello, World!')
在输入文本之前,可以先使用 clear()
方法清空输入框中的原有内容,确保输入的文本是准确的。另外,如果需要输入特殊字符,可以使用 Keys
类来模拟按键操作。
点击元素
使用 click()
方法可以点击元素。这在模拟用户点击按钮、链接等操作时非常常用。
python"># 查找 ID 为 'button_id' 的按钮元素
button_element = driver.find_element_by_id('button_id')
# 点击按钮
button_element.click()
在点击元素之前,可以先使用 is_enabled()
和 is_displayed()
方法来检查元素是否可用和可见,避免因元素不可用或不可见而导致点击失败。
2.2.5 等待页面加载
在网页中,有些元素可能需要一定的时间才能加载完成,因此需要使用等待机制。Selenium 提供了两种等待方式:显式等待和隐式等待。
显式等待
显式等待是指在代码中指定一个条件,直到该条件满足为止。这种方式可以让我们更加精确地控制等待时间,避免不必要的等待。
python">from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC# 等待最多 10 秒,直到 ID 为 'element_id' 的元素可见
element = WebDriverWait(driver, 10).until(EC.visibility_of_element_located((By.ID, 'element_id'))
)
显式等待可以根据不同的条件进行等待,如元素可见、元素可点击、元素存在等。在实际应用中,要根据具体的需求选择合适的条件。另外,为了避免等待时间过长,可以设置一个合理的超时时间。
隐式等待
隐式等待是指在查找元素时,等待一段时间,如果在这段时间内元素没有出现,则抛出异常。这种方式比较简单,只需要设置一次等待时间,后续所有的元素查找操作都会自动应用这个等待时间。
python"># 设置隐式等待时间为 10 秒
driver.implicitly_wait(10)
隐式等待适用于页面加载速度相对稳定的情况。但是,如果页面中有一些元素加载时间较长,使用隐式等待可能会导致整个程序的运行时间过长。因此,在实际应用中,可以结合显式等待和隐式等待来提高效率。
2.2.6 关闭浏览器
使用 quit()
方法可以关闭浏览器。这是在爬虫程序结束时必须要执行的操作,否则浏览器进程可能会一直存在,占用系统资源。
python"># 关闭浏览器
driver.quit()
在关闭浏览器之前,可以先保存一些必要的数据,如爬取到的信息、浏览器的会话状态等。另外,为了确保浏览器能够正常关闭,可以使用 try...finally
语句来保证 quit()
方法一定会被执行。
另外要注意的是:
浏览器驱动实例不是线程安全的,这意味着在多线程环境下,如果多个线程同时操作同一个浏览器驱动实例,可能会导致数据不一致、操作冲突等问题。例如,一个线程正在点击某个元素,而另一个线程同时在查找另一个元素,这可能会导致浏览器的行为变得不可预测。
因此,在多线程环境下,每个线程都应该有自己独立的浏览器驱动实例,避免多个线程共享同一个实例。
三、Selenium 爬取动漫网站流程
Step1:安装Python的Selenium 库及浏览器驱动
python">pip install selenium
# 记得下载对应浏览器的driver,推荐ChromeDriver
与BeautifulSoup不同在于,除了对应的Selenium 库以外要使用 Selenium,得先下载对应浏览器的驱动,比如 Chrome 浏览器就得下载 ChromeDriver。把驱动的路径配置好,这样 Selenium 才能和浏览器 “沟通”。
这里我们使用谷歌浏览器的驱动就行,对应资源大家可自行自行或者到