当前位置:首页>python>Python 零基础100天—Day79 Selenium 自动化

Python 零基础100天—Day79 Selenium 自动化

  • 2026-08-28 15:07:37
Python 零基础100天—Day79 Selenium 自动化

🐍 Python Day79:Selenium 自动化 — 让浏览器听你的

🕐 预计用时:3-4 小时 | 🎯 目标:掌握 Selenium 浏览器自动化、元素定位、等待策略和模拟操作


📖 今日目录

  1. Selenium 是什么?
  2. 环境搭建
  3. 浏览器控制
  4. 元素定位(8种方式)
  5. 元素操作
  6. 等待策略
  7. 实战:自动登录
  8. 实战:自动搜索
  9. 今日练习
  10. 今日小结

1. Selenium 是什么?

Selenium 是最流行的浏览器自动化工具——用代码控制浏览器做任何人类能做的事情:点击按钮、填写表单、滚动页面、截取屏幕……

# Selenium 能做什么?
# ✅ 自动化测试(Web 应用的功能测试)
# ✅ 网页数据采集(对付 JavaScript 动态渲染页面)
# ✅ 自动化操作(批量注册、自动签到、自动下单)
# ✅ 截图和 PDF 生成

# vs requests + BeautifulSoup:
# requests    → 获取静态 HTML(服务器返回什么拿什么)
# Selenium    → 控制真实浏览器(能执行 JS、点击按钮、处理登录)

# 类比:
# requests = 看照片(只能看,不能操作)
# Selenium = 远程桌面(能看,能点,能输入,完全操控)
特性
requests
Selenium
JavaScript 渲染
❌ 不能
✅ 能
点击/输入
❌ 不能
✅ 能
速度
⚡ 极快
🐢 较慢
资源占用
极少
较多(启动浏览器)
反爬绕过
较难
较容易
适用场景
API / 静态页面
动态页面 / 需要交互

2. 环境搭建

# 1. 安装 Selenium
pip install selenium

# 2. 安装浏览器驱动
# 方式1:自动管理(推荐!Selenium 4.6+)
from selenium import webdriver
driver = webdriver.Chrome()  # 自动下载匹配的 ChromeDriver

# 方式2:手动安装
# 下载 ChromeDriver: https://chromedriver.chromium.org/
# 放到系统 PATH 中

# 3. 验证安装
from selenium import webdriver
driver = webdriver.Chrome()
driver.get('https://www.python.org')
print(driver.title)  # "Welcome to Python.org"
driver.quit()        # 关闭浏览器
# 完整的启动配置
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.chrome.service import Service

# Chrome 选项
options = Options()
options.add_argument('--window-size=1920,1080')  # 窗口大小
options.add_argument('--disable-gpu')             # 禁用 GPU
options.add_argument('--no-sandbox')              # Linux 服务器需要
options.add_argument('--disable-dev-shm-usage')   # 共享内存限制

# 无头模式(不显示浏览器窗口,后台运行)
# options.add_argument('--headless')

# 启动浏览器
driver = webdriver.Chrome(options=options)

# 常用操作
driver.get('https://www.baidu.com')  # 打开网页
print(driver.title)                   # 获取标题
print(driver.current_url)             # 获取当前 URL
print(driver.page_source)             # 获取页面 HTML(全部,含 JS 渲染后)

# 关闭
driver.quit()   # 关闭浏览器和驱动进程
# driver.close()  # 只关闭当前标签页

💡 driver.quit() vs driver.close():

• driver.quit():关闭所有标签页 + 退出浏览器 + 结束驱动进程(推荐!)
• driver.close():只关闭当前标签页,浏览器和驱动还在

始终用 driver.quit(),否则浏览器进程会残留在内存中。


3. 浏览器控制

from selenium import webdriver

driver = webdriver.Chrome()

# === 页面导航 ===
driver.get('https://www.baidu.com')          # 打开 URL
driver.back()                                  # 后退
driver.forward()                               # 前进
driver.refresh()                               # 刷新

# === 窗口管理 ===
driver.maximize_window()                       # 最大化
driver.minimize_window()                       # 最小化
driver.set_window_size(1024, 768)              # 设置大小
driver.set_window_position(0, 0)              # 设置位置

# === 标签页管理 ===
# 打开新标签页
driver.execute_script("window.open('https://www.python.org', '_blank');")

# 获取所有标签页句柄
handles = driver.window_handles
print(f'标签页数量: {len(handles)}')

# 切换到第二个标签页
driver.switch_to.window(handles[1])

# 关闭当前标签页
driver.close()

# 切回第一个标签页
driver.switch_to.window(handles[0])

# === JavaScript 执行 ===
driver.execute_script("alert('Hello from Selenium!');")
driver.execute_script("window.scrollTo(0, 1000);")  # 滚动到页面中部
driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")  # 滚动到底部

# 返回元素的位置和大小
element = driver.find_element('id', 'myId')
position = driver.execute_script(
    "return arguments[0].getBoundingClientRect();", element
)
print(f'位置: x={position["x"]}, y={position["y"]}')
print(f'大小: w={position["width"]}, h={position["height"]}')

# === 截图 ===
driver.save_screenshot('screenshot.png')              # 整个页面
element.screenshot('element.png')                     # 单个元素截图

# === 获取 Cookies ===
cookies = driver.get_cookies()
for cookie in cookies:
    print(f'{cookie["name"]}: {cookie["value"]}')

# === 执行异步 JS ===
driver.execute_async_script("""
    // 模拟异步操作
    setTimeout(function() {
        document.title = 'Modified by Selenium';
        arguments[arguments.length - 1]('done');
    }, 2000);
""")

4. 元素定位(8种方式)

Selenium 提供了 8 种方式来定位页面上的元素。掌握这 8 种,就能找到页面上的任何东西。

from selenium.webdriver.common.by import By

driver.get('https://www.baidu.com')

# === 1. ID 定位(最稳定,优先使用)===
search_box = driver.find_element(By.ID, 'kw')

# === 2. NAME 定位 ===
search_box = driver.find_element(By.NAME, 'wd')

# === 3. CLASS_NAME 定位 ===
search_box = driver.find_element(By.CLASS_NAME, 's_ipt')

# === 4. TAG_NAME 定位 ===
all_inputs = driver.find_elements(By.TAG_NAME, 'input')

# === 5. LINK_TEXT 定位(精确匹配链接文字)===
link = driver.find_element(By.LINK_TEXT, '新闻')

# === 6. PARTIAL_LINK_TEXT(部分匹配链接文字)===
link = driver.find_element(By.PARTIAL_LINK_TEXT, '新')

# === 7. CSS_SELECTOR 定位(最灵活!)===
# 通过 ID
search_box = driver.find_element(By.CSS_SELECTOR, '
#kw')
# 通过 class
search_box = driver.find_element(By.CSS_SELECTOR, '.s_ipt')
# 通过属性
search_box = driver.find_element(By.CSS_SELECTOR, 'input[name="wd"]')
# 父子关系
search_box = driver.find_element(By.CSS_SELECTOR, 'form#form input.s_ipt')
# 属性包含
link = driver.find_element(By.CSS_SELECTOR, 'a[href*="news"]')

# === 8. XPATH 定位(最强大!能定位任何元素)===
# 通过属性
search_box = driver.find_element(By.XPATH, '//input[@id="kw"]')
# 通过文本
link = driver.find_element(By.XPATH, '//a[text()="新闻"]')
# 包含某属性值
link = driver.find_element(By.XPATH, '//a[contains(@href, "news")]')
# 父元素
parent = driver.find_element(By.XPATH, '//input[@id="kw"]/..')
# 兄弟元素
next_sibling = driver.find_element(By.XPATH, '//input[@id="kw"]/following-sibling::*')
# 多条件
element = driver.find_element(By.XPATH, '//input[@type="text" and @name="wd"]')

📋 8 种定位方式速查

定位方式
By 常量
示例
推荐度
ID
By.IDfind_element(By.ID, 'kw')
⭐⭐⭐⭐⭐
Name
By.NAMEfind_element(By.NAME, 'wd')
⭐⭐⭐⭐
Class
By.CLASS_NAMEfind_element(By.CLASS_NAME, 'ipt')
⭐⭐⭐
Tag
By.TAG_NAMEfind_element(By.TAG_NAME, 'input')
⭐⭐
Link Text
By.LINK_TEXTfind_element(By.LINK_TEXT, '新闻')
⭐⭐⭐
Partial Link
By.PARTIAL_LINK_TEXTfind_element(By.PARTIAL_LINK_TEXT, '新')
⭐⭐
CSS Selector
By.CSS_SELECTORfind_element(By.CSS_SELECTOR, '#kw')
⭐⭐⭐⭐
XPath
By.XPATHfind_element(By.XPATH, '//input[@id="kw"]')
⭐⭐⭐⭐⭐

💡 定位优先级:

1. ID — 最稳定,页面上唯一,不会变
2. CSS Selector — 灵活,速度快,推荐日常使用
3. XPath — 最强大,能定位任何元素,但速度稍慢
4. Name / Class — 简单场景可用
5. Link Text — 专门用于链接

find_elements(复数)返回列表,找不到返回空列表;find_element 找不到抛异常。


5. 元素操作

from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.action_chains import ActionChains

# === 基本操作 ===
element = driver.find_element(By.ID, 'username')

element.send_keys('hello')                    # 输入文字
element.send_keys(Keys.ENTER)                 # 按回车
element.send_keys(Keys.TAB)                   # 按 Tab
element.send_keys(Keys.CONTROL, 'a')          # Ctrl+A 全选
element.send_keys(Keys.CONTROL, 'c')          # Ctrl+C 复制
element.clear()                                # 清空输入框
element.click()                                # 点击
element.submit()                               # 提交表单(Selenium 4 已弃用,建议用 click() 点击提交按钮)

# === 获取元素信息 ===
element.text                                    # 获取文本内容
element.get_attribute('href')                   # 获取属性值
element.get_attribute('value')                  # 获取输入框的值
element.get_attribute('class')                  # 获取 class
element.is_displayed()                          # 是否可见
element.is_enabled()                            # 是否可用
element.is_selected()                           # 是否选中(checkbox/radio)
element.size                                    # 大小 {'height': 30, 'width': 200}
element.location                                # 位置 {'x': 100, 'y': 200}
element.tag_name                                # 标签名

# === 下拉框操作 ===
from selenium.webdriver.support.ui import Select

select = Select(driver.find_element(By.ID, 'city'))
select.select_by_visible_text('北京')          # 按文字选择
select.select_by_value('beijing')              # 按 value 选择
select.select_by_index(0)                      # 按索引选择
select.deselect_all()                          # 取消所有选择(多选框)

# === 鼠标操作(ActionChains)===
actions = ActionChains(driver)

# 悬停
menu = driver.find_element(By.ID, 'menu')
actions.move_to_element(menu).perform()

# 右键
actions.context_click(element).perform()

# 双击
actions.double_click(element).perform()

# 拖拽
source = driver.find_element(By.ID, 'draggable')
target = driver.find_element(By.ID, 'droppable')
actions.drag_and_drop(source, target).perform()

# 悬停 → 点击子菜单
actions.move_to_element(menu).pause(0.5).click(submenu).perform()

6. 等待策略

网页加载需要时间,元素不会立即出现。等待是 Selenium 最重要的概念之一。

# ❌ 错误做法:用 sleep 等待(慢且不可靠)
import time
time.sleep(5)  # 等 5 秒,不管元素出没出现

# ✅ 正确做法:显式等待(等到元素出现为止)
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

# === 显式等待(推荐!)===
# 最多等 10 秒,每 0.5 秒检查一次,直到条件满足
wait = WebDriverWait(driver, 10, poll_frequency=0.5)

# 等待元素出现
element = wait.until(EC.presence_of_element_located((By.ID, 'kw')))

# 等待元素可点击
button = wait.until(EC.element_to_be_clickable((By.ID, 'su')))

# 等待元素可见
element = wait.until(EC.visibility_of_element_located((By.CLASS_NAME, 'result')))

# 等待元素消失(如加载动画消失)
wait.until(EC.invisibility_of_element_located((By.CLASS_NAME, 'loading')))

# 等待标题包含某文字
wait.until(EC.title_contains('百度'))

# 等待 URL 包含某文字
wait.until(EC.url_contains('search'))

# 等待 alert 出现
alert = wait.until(EC.alert_is_present())
alert.accept()

# === 隐式等待(全局设置,不推荐单独使用)===
driver.implicitly_wait(10)  # 所有 find_element 最多等 10 秒

📋 常用等待条件

条件
说明
presence_of_element_located
元素出现在 DOM 中(不一定可见)
visibility_of_element_located
元素可见(有宽高)
element_to_be_clickable
元素可见且可点击
text_to_be_present_in_element
元素内包含指定文字
invisibility_of_element_located
元素不可见或不存在
frame_to_be_available_and_switch_to_it
iframe 可用并切换
alert_is_present
alert 弹窗出现
number_of_windows_to_be
窗口数量等于指定值

⚠️ 等待策略总结:

❌ sleep(5):永远不要用!慢且不可靠
⚠️ implicitly_wait(10):全局隐式等待,对某些条件无效
✅ WebDriverWait + expected_conditions:精确等待,条件满足立即继续


7. 实战:自动百度搜索

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import time

def baidu_search(keyword):
    """自动百度搜索"""
    driver = webdriver.Chrome()
    driver.maximize_window()

    try:
        # 1. 打开百度
        driver.get('https://www.baidu.com')
        print(f'✅ 打开百度: {driver.title}')

        # 2. 等待搜索框出现
        wait = WebDriverWait(driver, 10)
        search_box = wait.until(
            EC.presence_of_element_located((By.ID, 'kw'))
        )

        # 3. 输入关键词
        search_box.clear()
        search_box.send_keys(keyword)
        print(f'✅ 输入关键词: {keyword}')

        # 4. 点击搜索按钮
        search_btn = driver.find_element(By.ID, 'su')
        search_btn.click()
        print('✅ 点击搜索')

        # 5. 等待搜索结果出现
        wait.until(
            EC.presence_of_element_located((By.CLASS_NAME, 'result'))
        )
        print('✅ 搜索结果已加载')

        # 6. 截图保存
        driver.save_screenshot('search_result.png')
        print('✅ 截图已保存')

        # 7. 获取搜索结果
        results = driver.find_elements(By.CSS_SELECTOR, '.result h3 a')
        print(f'\n📋 搜索结果(前5条):')
        for i, result in enumerate(results[:5]):
            print(f'  {i+1}. {result.text}')
            print(f'     {result.get_attribute("href")}')

        return results

    except Exception as e:
        print(f'❌ 出错了: {e}')
        driver.save_screenshot('error.png')

    finally:
        driver.quit()
        print('✅ 浏览器已关闭')

# 执行搜索
baidu_search('Python 教程')

8. 实战:处理弹窗和 iframe

# === 处理 alert 弹窗 ===
driver.get('https://example.com')

# 触发 alert(例如点击某个按钮)
driver.find_element(By.ID, 'alertBtn').click()

# 等待并切换到 alert
wait = WebDriverWait(driver, 10)
alert = wait.until(EC.alert_is_present())

# 获取 alert 文字
print(f'Alert 内容: {alert.text}')

# 操作
alert.accept()       # 点击"确定"
# alert.dismiss()    # 点击"取消"
# alert.send_keys('输入内容')  # 如果是 prompt

# === 处理 iframe ===
# iframe 是页面中嵌套的另一个页面,需要先切换才能操作内部元素

# 方式1:通过 iframe 的 name 或 id 切换
driver.switch_to.frame('iframe_name')

# 方式2:通过元素切换
iframe = driver.find_element(By.ID, 'myFrame')
driver.switch_to.frame(iframe)

# 方式3:通过索引切换(0 = 第一个 iframe)
driver.switch_to.frame(0)

# 操作 iframe 内的元素
driver.find_element(By.ID, 'innerElement').click()

# 切回主页面(必须!)
driver.switch_to.default_content()

# === 处理新窗口/标签页 ===
# 点击某个链接打开了新窗口
driver.find_element(By.LINK_TEXT, '新窗口链接').click()

# 获取所有窗口句柄
handles = driver.window_handles

# 切换到新窗口(最后一个)
driver.switch_to.window(handles[-1])
print(f'新窗口标题: {driver.title}')

# 操作新窗口...

# 切回原窗口
driver.switch_to.window(handles[0])

# === 处理文件上传 ===
# 找到 file input 元素
file_input = driver.find_element(By.CSS_SELECTOR, 'input[type="file"]')

# 直接发送文件路径(不需要点击弹窗!)
file_input.send_keys('/path/to/file.jpg')

# === 处理下拉框(select)===
from selenium.webdriver.support.ui import Select

select_element = Select(driver.find_element(By.ID, 'country'))
select_element.select_by_visible_text('中国')  # 按文字
select_element.select_by_value('CN')            # 按 value
select_element.select_by_index(0)               # 按索引

9. 今日练习

🏋️ 练习 1:自动打开网页

# 用 Selenium 打开 Python 官网 (python.org)
# 获取:页面标题、当前 URL、页面源码长度
# 截图保存为 python_org.png
# 然后关闭浏览器

🏋️ 练习 2:自动填写表单

# 创建一个简单的 HTML 表单页面
# 用 Selenium 自动填写所有字段:
# - 文本输入(姓名、邮箱)
# - 下拉选择(城市)
# - 单选按钮(性别)
# - 复选框(爱好)
# - 提交表单

🏋️ 练习 3:百度搜索并提取结果

# 自动搜索"Python selenium"
# 提取前 10 条搜索结果的标题和链接
# 保存为 CSV 文件

10. 今日小结

知识点
核心内容
浏览器控制
get / back / forward / refresh / maximize / quit
元素定位
8 种方式:ID > CSS > XPath > Name > Class > Tag > LinkText
元素操作
click / send_keys / clear / text / get_attribute
等待策略
WebDriverWait + expected_conditions(显式等待)
特殊处理
alert / iframe / 新窗口 / 文件上传 / 下拉框
高级操作
ActionChains(悬停/拖拽/双击)/ execute_script

🚀 明日预告:Day 80 — Selenium 进阶

无头模式、反检测技巧、数据采集实战——用 Selenium 绕过反爬,从动态页面批量采集数据。

最新文章

随机文章