学习爬虫第五天:自动化爬虫

自动化爬虫


下载selenium自动爬虫工具

根据当时最新浏览器版本,下载最新版本,不然会出现很多问题

google

查看google版本

没有更新的更新到最新版本

下载最新的ChromeDriver版本

Google Chrome WebDriver(ChromeDriver)下载

edge

查看edge版本

没有更新的更新到最新版本

去下载最新版本的 msedgedriver

Microsoft Edge WebDriver(msedgedriver)下载

使用selenium (一般模拟get请求)

安装selenium

复制代码
pip install selenium

创建Chrome浏览器对象

复制代码
from selenium import webdriver  
from selenium.webdriver.chrome.service import Service

# Chromedriver的位置  
Chromedriver_path=r'E:\chromedriver.exe'  
service=Service(executable_path=Chromedriver_path)  
# 创建Chrome浏览器对象  
driver1=webdriver.Chrome(service=service)  

url='https://www.baidu.com'  
# 发送get请求
driver1.get(url)

创建Edge浏览器对象

复制代码
from selenium import webdriver  
from selenium.webdriver.chrome.service import Service

# Edgedriver的位置  
Edgedriver_path=r'E:\msedgedriver.exe'  
service=Service(executable_path=Edgedriver_path)  
# 创建Edge浏览器对象  
driver2=webdriver.Edge(service=service)  
  
url='https://www.baidu.com'  
# 发送get请求
driver2.get(url)

driver.get(url)响应页面的常用属性和方法

类型 名称 >>>>>>>>>>>>>>作用说明 示例
属性 current_url 获取当前页面的 URL driver.current_url
title 获取当前页面标题 driver.title
page_source 获取页面的 HTML 源代码 driver.page_source
window_handles 获取所有窗口的句柄列表 driver.window_handles
current_window_handle 获取当前窗口句柄 driver.current_window_handle
name 获取当前浏览器名称 driver.name
页面操作 get(url) 打开指定 URL driver.get("https://www.baidu.com")
back() 模拟浏览器"后退" driver.back()
forward() 模拟浏览器"前进" driver.forward()
refresh() 刷新页面 driver.refresh()
查找元素 find_element(By, value) 查找单个元素 driver.find_element(By.ID, "kw")
find_elements(By, value) 查找多个元素(列表) driver.find_elements(By.TAG_NAME, "a")
执行脚本 execute_script(js_code) 执行 JS 脚本 driver.execute_script("alert('hi')")
截图 save_screenshot(file) 保存当前页面截图 driver.save_screenshot("baidu.png")
窗口控制 maximize_window() 最大化窗口 driver.maximize_window()
minimize_window() 最小化窗口 driver.minimize_window()
set_window_size(width, height) 设置窗口大小 driver.set_window_size(1280, 720)
框架与窗口切换 switch_to.frame(name_or_element) 切换到 iframe driver.switch_to.frame("frame1")
switch_to.default_content() 切回主文档 driver.switch_to.default_content()
switch_to.window(handle) 切换窗口 driver.switch_to.window(driver.window_handles[1])
警告框 switch_to.alert 获取弹出框对象 alert = driver.switch_to.alert
Cookies 操作 get_cookies() 获取所有 cookies driver.get_cookies()
add_cookie(cookie_dict) 添加 cookie driver.add_cookie({"name": "test", "value": "123"})
delete_all_cookies() 删除所有 cookies driver.delete_all_cookies()
等待 implicitly_wait(seconds) 隐式等待元素加载 driver.implicitly_wait(10)
关闭 close() 关闭当前窗口 driver.close()
quit() 关闭所有窗口并退出浏览器 driver.quit()

Chrome浏览器配置 (edge浏览器同理)

复制代码
# Chrome浏览器配置 
options=ChromeOptions()  
# 
# 后台运行  
options.add_argument('--headless')  
  
# 创建Chrome浏览器对象  
driver1=webdriver.Chrome(service=service,options=options)

Chrome 常用的 options.add_argument() 参数 (edge浏览器同理)

参数 作用 备注
--headless 无界面模式,在后台运行浏览器 常用于服务器或自动化脚本
--window-size=1920,1080 设置窗口大小 部分网页需要特定分辨率才能加载完整内容
--incognito 启动无痕模式 不保存缓存、Cookies
--start-maximized 启动时最大化 适用于可视化调试
--disable-extensions 禁用扩展插件 提高运行速度
--disable-infobars 禁用"Chrome 正在受到自动软件控制"的提示 让界面更干净
--ignore-certificate-errors 忽略 HTTPS 证书错误 爬取测试网站时常用
--disable-popup-blocking 禁用弹窗拦截 防止脚本卡死
--user-agent="xxx" 自定义 User-Agent 用于伪装成特定浏览器
--lang=zh-CN,zh 设置浏览器语言 常用于中文页面加载正确
--mute-audio 静音模式 视频自动播放时不出声
--blink-settings=imagesEnabled=false 禁止加载图片 加快加载速度(爬虫常用)
--proxy-server=http://IP:PORT 设置代理服务器 用于反爬或国外访问
--disable-blink-features=AutomationControlled 伪装,隐藏"被自动化控制"特征 防止网站检测 Selenium

注意:有个小缺点就是 打开的浏览器在访问请求时间过久会自动退出

复制代码
# 让浏览器保持运行 不会占用很多cpu内存
while True:  
    time.sleep(1)

定位元素

find_element / find_elements()

定位方式 参数写法 示例 说明
By.ID find_element(By.ID, "kw") 定位 id="kw" 的元素 精准、最快
By.NAME find_element(By.NAME, "wd") 定位 name="wd" 的输入框 适用于表单元素
By.CLASS_NAME find_element(By.CLASS_NAME, "btn") 定位 class="btn" 的元素 不能有空格(单类)
By.TAG_NAME find_element(By.TAG_NAME, "input") 定位第一个 <input> 标签 适用于通用标签查找
By.LINK_TEXT find_element(By.LINK_TEXT, "新闻") 精确匹配链接文字 匹配 <a> 的文本
By.PARTIAL_LINK_TEXT find_element(By.PARTIAL_LINK_TEXT, "新") 模糊匹配链接文字 模糊匹配 <a> 文本
By.XPATH find_element(By.XPATH, '//*[@id="kw"]') 根据 XPath 表达式定位 功能最强大
By.CSS_SELECTOR find_element(By.CSS_SELECTOR, "#kw") 使用 CSS 选择器定位 高效灵活

JavaScript 脚本

使用方法

复制代码
# script → 要执行的 JavaScript 代码字符串
driver.execute_script(script)

script参数常见的 JS 定位元素方式

JS 语句 说明 示例
document.getElementById("id") 按 ID 定位 获取单个元素
document.getElementsByClassName("class") 按类名定位 返回 HTMLCollection
document.getElementsByTagName("tag") 按标签名定位 返回所有相同标签元素
document.querySelector("css选择器") 使用 CSS 选择器定位 最灵活
document.querySelectorAll("css选择器") 获取所有匹配的元素 返回 NodeList

页面元素常用属性

属性 说明 示例
id 元素的 id element.id
className 元素的 class 属性值 element.className
tagName 元素的标签名(大写) element.tagName"DIV"
innerHTML 元素内部的 HTML 字符串 element.innerHTML
outerHTML 包含自身的 HTML 字符串 element.outerHTML
innerText 元素内部的纯文本(忽略 HTML 标签) element.innerText
textContent 元素的所有文本(包括隐藏文本) element.textContent
value 输入框、文本域的值 element.value
href 超链接的链接地址 element.href
src 图片或脚本的资源地址 element.src
style 元素的样式对象 element.style.color
text 获取元素文本 element.text

页面元素常用方法

方法 说明 示例
click() 模拟鼠标点击 element.click()
focus() 聚焦输入框 element.focus()
blur() 失焦 element.blur()
scrollIntoView() 滚动页面直到元素可见 element.scrollIntoView()
setAttribute(name, value) 设置属性 element.setAttribute("value", "新内容")
getAttribute(name) 获取属性值 element.getAttribute("href")
removeAttribute(name) 移除属性 element.removeAttribute("disabled")
appendChild(node) 添加子元素 parent.appendChild(child)
remove() 删除元素自身 element.remove()
querySelector(selector) 查找子元素 element.querySelector(".child")
querySelectorAll(selector) 查找所有子元素 element.querySelectorAll("li")
send_keys(str) 在输入框中输入文字 element.send_keys("你好")
clear() 清空输入框内容 element.clear()

控制鼠标和键盘

导入ActionChains库

复制代码
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.keys import Keys

常用鼠标操作方法

方法 >>>>>>>>>>>>>说明 示例
click(element) 点击指定元素 ActionChains(driver).click(btn).perform()
double_click(element) 双击元素 ActionChains(driver).double_click(btn).perform()
context_click(element) 右击元素 ActionChains(driver).context_click(btn).perform()
move_to_element(element) 鼠标移动到元素上 ActionChains(driver).move_to_element(menu).perform()
click_and_hold(element) 按住元素不放 ActionChains(driver).click_and_hold(ele).perform()
release(element) 释放鼠标 ActionChains(driver).release(ele).perform()
drag_and_drop(source, target) 拖拽元素到目标 ActionChains(driver).drag_and_drop(src, dst).perform()
drag_and_drop_by_offset(element, x, y) 按偏移量拖拽 ActionChains(driver).drag_and_drop_by_offset(ele, 100, 50).perform()
move_by_offset(x, y) 鼠标移动到相对坐标 ActionChains(driver).move_by_offset(50, 20).perform()
move_to_element_with_offset(ele, x, y) 相对于元素偏移移动 ActionChains(driver).move_to_element_with_offset(ele, 10, 5).perform()

常用键盘操作方法

send_keys()常用的按键组合( 简单一些)

按键 常量写法 >>>>>>>>>>>>>>>>>>作用说明 示例(element=driver.get(url).find_element())
回车 Keys.ENTER / Keys.RETURN 提交表单或执行搜索 element.send_keys(Keys.ENTER)
退格 Keys.BACKSPACE 删除一个字符 element.send_keys(Keys.BACKSPACE)
删除 Keys.DELETE 删除选中文本或后方字符 element.send_keys(Keys.DELETE)
制表键 Keys.TAB 切换到下一个输入框 element.send_keys(Keys.TAB)
空格 Keys.SPACE 输入空格或触发复选框 element.send_keys(Keys.SPACE)
方向键上 Keys.ARROW_UP 模拟↑键 element.send_keys(Keys.ARROW_UP)
方向键下 Keys.ARROW_DOWN 模拟↓键 element.send_keys(Keys.ARROW_DOWN)
方向键左 Keys.ARROW_LEFT 模拟←键 element.send_keys(Keys.ARROW_LEFT)
方向键右 Keys.ARROW_RIGHT 模拟→键 element.send_keys(Keys.ARROW_RIGHT)
Esc键 Keys.ESCAPE 取消、退出弹窗 element.send_keys(Keys.ESCAPE)
全选 Keys.CONTROL, "a" 全选文本 element.send_keys(Keys.CONTROL, "a")
复制 Keys.CONTROL, "c" 复制文本 element.send_keys(Keys.CONTROL, "c")
粘贴 Keys.CONTROL, "v" 粘贴文本 element.send_keys(Keys.CONTROL, "v")
剪切 Keys.CONTROL, "x" 剪切文本 element.send_keys(Keys.CONTROL, "x")
PageUp Keys.PAGE_UP 向上翻页 element.send_keys(Keys.PAGE_UP)
PageDown Keys.PAGE_DOWN 向下翻页 element.send_keys(Keys.PAGE_DOWN)

ActionChains常用的按键组合 ( 会更复杂一点 )

可以实现动作的"按下 → 保持 → 弹起"全过程

操作类型 方法/按键 >>>>>>>>>>>>作用说明 示例 (actions = ActionChains(driver.get(url)))
输入文字 send_keys("text") 向当前焦点或指定元素输入文字 actions.send_keys("hello").perform()
向指定元素输入 send_keys_to_element(element, "内容") 指定目标元素输入文本 actions.send_keys_to_element(input_box, "Python").perform()
按下某个键 key_down(Keys.CONTROL) 模拟按住一个键(不松开) actions.key_down(Keys.CONTROL).perform()
释放某个键 key_up(Keys.CONTROL) 模拟释放某个键 actions.key_up(Keys.CONTROL).perform()
组合键(Ctrl+A) key_down() + send_keys() + key_up() 执行组合快捷键 actions.key_down(Keys.CONTROL).send_keys("a").key_up(Keys.CONTROL).perform()
复制(Ctrl+C) 同上 模拟复制操作 actions.key_down(Keys.CONTROL).send_keys("c").key_up(Keys.CONTROL).perform()
粘贴(Ctrl+V) 同上 模拟粘贴操作 actions.key_down(Keys.CONTROL).send_keys("v").key_up(Keys.CONTROL).perform()
剪切(Ctrl+X) 同上 模拟剪切操作 actions.key_down(Keys.CONTROL).send_keys("x").key_up(Keys.CONTROL).perform()
撤销(Ctrl+Z) 同上 模拟撤销 actions.key_down(Keys.CONTROL).send_keys("z").key_up(Keys.CONTROL).perform()
方向键 Keys.ARROW_UP / DOWN / LEFT / RIGHT 模拟方向键操作 actions.send_keys(Keys.ARROW_DOWN).perform()
回车 Keys.ENTER 模拟回车(提交表单、搜索) actions.send_keys(Keys.ENTER).perform()
删除 Keys.DELETE 删除选中内容 actions.send_keys(Keys.DELETE).perform()
Esc键 Keys.ESCAPE 模拟退出操作 actions.send_keys(Keys.ESCAPE).perform()
Tab键 Keys.TAB 切换到下一个输入框 actions.send_keys(Keys.TAB).perform()
PageUp / PageDown Keys.PAGE_UP / PAGE_DOWN 模拟翻页 actions.send_keys(Keys.PAGE_DOWN).perform()

send_keys()ActionChains 的区别对比

对比项 send_keys() ActionChains
主要用途 用于向元素发送文本或简单按键(如输入框、搜索栏) 用于执行复杂交互操作(键盘组合、鼠标动作、拖拽等)
作用对象 直接作用于单个 WebElement 元素 作用于整个浏览器上下文(可同时操作多个元素)
执行方式 调用后立即执行(同步执行) 需要 .perform() 才会执行动作链
代码复杂度 简单、一行完成 稍复杂,需要链式调用
可执行操作类型 文本输入、单键(ENTERTAB 等) 多键组合(如 Ctrl + A)、鼠标点击、双击、拖拽、悬停等
焦点要求 元素必须可聚焦(如输入框) 可操作任意元素或坐标位置
兼容性 对输入框、表单兼容性好 对复杂交互(如游戏、拖拽UI)更强
内部机制 模拟用户键入字符(输入事件) 模拟真实键盘/鼠标动作事件
性能表现 轻量、执行快 稍重、适合批量操作或复杂动作
典型使用场景 登录输入框、搜索框、表单填写 拖拽文件、全选复制、鼠标悬停、组合键输入等

案例:给虎牙直播吃鸡所有主播发送弹幕 ( https://www.huya.com/ )

分析步骤:

  1. 登录虎牙

  2. 找到吃鸡主播数据

  3. 通过数据进入主播直播间

  4. 发送弹幕

    模拟上述操作进行自动化发送弹幕(登录验证滑块需要手动拖动)

    import time

    import requests
    from selenium import webdriver
    from selenium.webdriver.common.by import By
    from selenium.webdriver.edge.service import Service
    from selenium.webdriver.support import expected_conditions
    from selenium.webdriver.support.wait import WebDriverWait

    edge浏览器下载的路径

    edge_path=r'E:\msedgedriver.exe'

    service =Service(executable_path=edge_path)

    driver=webdriver.Edge(service=service)

    login_url='https://www.huya.com'
    driver.get(login_url)

    窗口最大化

    driver.maximize_window()

    点击登录 直到登录框可见

    login_span=driver.find_element(By.CSS_SELECTOR,'#J_duyaHeaderRight>div > div:nth-child(2) > a')

    login_span=WebDriverWait(driver,10,0.5).until(expected_conditions.visibility_of_element_located((By.CSS_SELECTOR,'#J_duyaHeaderRight>div > div:nth-child(2) > a')))

    login_span.click()

    切换到登录框里面

    login_iframe=driver.find_element(By.CSS_SELECTOR,'#UDBSdkLgn-box>iframe')

    driver.switch_to.frame(login_iframe)

    发现并切换到登录框

    WebDriverWait(driver,10,0.5).until(expected_conditions.frame_to_be_available_and_switch_to_it((By.CSS_SELECTOR,'#UDBSdkLgn-box>iframe')))

    print(driver.page_source)

    输入账号 直到账号框可见

    account = driver.find_element(By.CSS_SELECTOR, '#username')

    account=WebDriverWait(driver,10,0.5).until(expected_conditions.visibility_of_element_located((By.CSS_SELECTOR, '#username')))

    account.send_keys('18200156497')

    输入密码

    password=driver.find_element(By.ID,'password')
    password.send_keys('20031124abc.')

    点击登录

    login_button=driver.find_element(By.CSS_SELECTOR,'#login-btn')
    login_button.click()

    等待移动验证滑块

    time.sleep(10)
    print('登录成功')

    获取吃鸡主播的房间列表

    pubg_url='https://live.huya.com/liveHttpUI/getLiveList'
    pubg_params={
    'iGid':'2793'
    }
    pubg_response=requests.get(pubg_url,params=pubg_params)

    print(json.dumps(pubg_response.json(),indent=4,ensure_ascii=False))

    记录当前主窗口

    main_window=driver.current_window_handle
    for pubg_room in pubg_response.json()['vList']:
    room_url=f'https://www.huya.com/{pubg_room["lProfileRoom"]}'
    # 主播名
    name=pubg_room['sNick']
    driver.execute_script(f'window.open("{room_url}")')
    driver.switch_to.window(driver.window_handles[-1])

    复制代码
     # 输入弹幕
     # Barrage_input_box = driver.find_element(By.ID, 'pub_msg_input')
     # 输入弹幕 直到弹幕框可见
     Barrage_input_box=WebDriverWait(driver,10,0.5).until(expected_conditions.visibility_of_element_located((By.ID,'pub_msg_input')))
    
     Barrage_input_box.send_keys(f'大吉大利,今晚吃鸡 {name}')
     # 点击发送
     send_button = driver.find_element(By.CSS_SELECTOR, '#msg_send_bt')
     send_button.click()
    
     # 可以看到弹幕发送成功效果
     time.sleep(3)
     # 关闭当前窗口
     driver.close()
     # 返回主窗口
     driver.switch_to.window(main_window)

    防止意外退出

    while True:
    time.sleep(1)

扩展技术

注意:Selenium 默认控制 当前激活的窗口(程序刚启动时就是第一个窗口),打开新窗口不会自动切换,需要显式调用 switch_to.window

技巧1:获取嵌套的html中的属性就使用iframe

解决方法

复制代码
url='https://www.mail.163.com'  
driver.get(url)  
# 定位到登录页面的iframe  
iframe=driver.find_element(By.CSS_SELECTOR,'#loginDiv>iframe')  
# 切换到iframe  
driver.switch_to.frame(iframe)

效果

技巧2:显示等待 ( 只有满足了条件才放过)

作用:当网页内容还没完全加载时,解决因为加载延迟而找不到元素。
代码模版

复制代码
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
# 一般timeout=10,poll_frequency=0.5
WebDriverWait(driver, timeout, poll_frequency).until(
    EC.条件((By.方式, "定位器"))
)

expected_conditions的方法( 判断元素是否为可用状态)

使用场景 典型情况 推荐等待条件(expected_conditions 方法说明
页面刚加载完但元素未渲染 页面使用 Vue/React、JS 异步加载 presence_of_element_located(locator) 等待元素出现在 DOM 中(可见与否都行)
点击按钮后出现新内容 弹出层、下拉菜单、登录输入框等 visibility_of_element_located(locator) 等待元素变得可见
切换 iframe 时 iframe 需要时间加载 frame_to_be_available_and_switch_to_it(locator) 等待并自动切换到 iframe
异步加载数据(Ajax) 点击加载按钮后表格更新 presence_of_element_located(locator) 等待新内容出现在页面
等待元素可点击 按钮被遮挡或未激活 element_to_be_clickable(locator) 确保元素能被点击
等待文字变化 状态提示 "加载中..." → "完成" text_to_be_present_in_element(locator, text_) 等待指定文字出现在元素中
页面跳转/刷新后操作 页面速度不稳定 presence_of_element_located(locator) 等目标元素重新加载
等待弹窗出现 页面 alert、confirm 对话框 alert_is_present() 等待弹窗出现
动态按钮状态变化 按钮从禁用 → 可用 element_to_be_clickable(locator) 等按钮恢复可交互
复杂动画或遮罩层结束 页面过渡动画还在执行 visibility_of_element_located(locator) 等动画结束后元素显示

如果你在阅读过程中也有新的见解,或者遇到类似问题,🥰不妨留言分享你的经验,让大家一起学习。

喜欢本篇内容的朋友,记得点个 👍点赞,收藏 并 关注我,这样你就不会错过后续的更多实用技巧和深度干货了!

期待在评论区看到你的声音,我们一起成长、共同进步!😊

相关推荐
m***记3 小时前
Python 自动化办公的 10 大脚本
windows·python·自动化
人间乄惊鸿客3 小时前
python - 第二天
python
江上月5133 小时前
django与vue3的对接流程详解(上)
后端·python·django
老歌老听老掉牙3 小时前
基于 PyQt5 实现刀具类型选择界面的设计与交互逻辑
python·qt·交互
可触的未来,发芽的智生3 小时前
触摸未来2025.10.09:记忆的突围,从64个神经元到人工海马体神经网络
人工智能·python·神经网络·机器学习·架构
川石课堂软件测试4 小时前
什么是BUG,你对BUG的了解有多少?
android·linux·服务器·python·功能测试·bug·安全性测试
风之所往_4 小时前
使用 openpyxl 生成 excel 折线图
python·excel·openpyxl
努力也学不会java4 小时前
【Java并发】揭秘Lock体系 -- 深入理解ReentrantReadWriteLock
java·开发语言·python·机器学习
我的xiaodoujiao7 小时前
从 0 到 1 搭建 Python 语言 Web UI自动化测试学习系列 15--二次开发--封装公共方法 3
python·学习·测试工具