目录
- 环境准备
- Selenium 基础操作
- 实战案例:登录微博并获取热搜榜
- 进阶技巧与最佳实践
- 重要注意事项(防封禁)
环境准备
在开始之前,请确保你已经安装了必要的软件和库。
a. 安装 Python
如果你的电脑上没有 Python,请先从 Python官网 下载并安装,安装时请勾选 "Add Python to PATH"。
b. 安装 Chrome 浏览器
Selenium 需要一个浏览器来驱动,我们使用最流行的 Chrome 浏览器,请确保你已安装最新版的 Chrome。
c. 安装 ChromeDriver
Selenium 本身不能直接控制浏览器,它需要通过一个叫做 WebDriver 的驱动程序来与浏览器进行通信,对于 Chrome,这个驱动就是 ChromeDriver。
如何安装 ChromeDriver:
- 查看你的 Chrome 版本:打开 Chrome,进入
设置->Chrome,记下你的 Chrome 版本号(0.6312.86)。 - 下载对应版本的 ChromeDriver:
- 访问 ChromeDriver 官方下载页面:https://googlechromelabs.github.io/chrome-for-testing/
- 找到与你 Chrome 版本最接近的
chromedriver下载链接。latest-release就可以。 - 下载适用于你操作系统的
zip压缩包(win64)。
- 配置环境变量:
- 推荐方法:将解压后的
chromedriver.exe(Windows) 或chromedriver(Mac/Linux) 文件放到 Python 的Scripts目录下。C:\Users\你的用户名\AppData\Local\Programs\Python\Python311\Scripts,这样你就可以在任何地方直接调用它。 - 替代方法:将解压后的文件放到一个固定路径(如
C:\chromedriver),然后在代码中指定其路径。
- 推荐方法:将解压后的
d. 安装 Selenium 库
打开你的终端或命令行工具,运行以下命令安装 Selenium:
pip install selenium
Selenium 基础操作
让我们先写一个简单的脚本,打开一个微博页面,并进行一些基本交互。
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import time
# --- 1. 初始化 WebDriver ---
# 方法一:chromedriver 在环境变量中,可以这样写
# driver = webdriver.Chrome()
# 方法二:chromedriver 不在环境变量中,需要指定其路径
# service = Service(executable_path='C:/path/to/your/chromedriver.exe')
# driver = webdriver.Chrome(service=service)
# 为了演示,我们假设 chromedriver 在环境变量中
driver = webdriver.Chrome()
# --- 2. 打开目标网页 ---
driver.get("https://weibo.com")
# 最大化窗口,方便观察
driver.maximize_window()
# --- 3. 元素定位与交互 ---
# 等待页面加载,并找到搜索框
# 使用 WebDriverWait 是更稳健的做法,可以避免页面加载慢导致找不到元素
try:
# 显式等待,最多等待10秒,直到搜索框出现
search_box = WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.CSS_SELECTOR, "input[data-attrid='search_input']"))
)
print("找到搜索框!")
# 在搜索框中输入内容
search_box.send_keys("Python自动化")
# 模拟按下回车键进行搜索
search_box.send_keys(Keys.ENTER)
print("已执行搜索。")
# 等待几秒,观察结果
time.sleep(5)
except Exception as e:
print(f"发生错误: {e}")
print("可能找不到元素,请检查选择器是否正确。")
# --- 4. 关闭浏览器 ---
# driver.quit() # 关闭整个浏览器,推荐使用
# driver.close() # 只关闭当前标签页
核心概念解释:
webdriver.Chrome(): 创建一个 Chrome 浏览器实例。driver.get(url): 打开指定的 URL。- *`driver.find_element(By., "selector")`**: 定位页面上的元素。
By.ID: 通过元素的id属性定位。By.NAME: 通过name属性定位。By.CLASS_NAME: 通过class属性定位。By.CSS_SELECTOR: 强大的 CSS 选择器定位方式(推荐)。By.XPATH: 通过 XPath 路径定位(功能强大,但有时不稳定)。
element.send_keys(): 向输入框中输入文本。element.click(): 点击元素(按钮、链接等)。WebDriverWait和EC: 显式等待,这是 Selenium 自动化中的最佳实践,它会等待某个条件(如元素出现、可点击)满足后再继续执行,而不是傻傻地time.sleep(),从而提高脚本的稳定性和执行效率。
实战案例:登录微博并获取热搜榜
这个案例更具代表性,因为它涉及到登录操作(通常有验证码)和动态数据加载。
目标:
- 登录微博。
- 访问热搜榜页面。
- 获取热搜榜前10名的标题、排名和热度。
代码实现:
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import time
# 初始化 WebDriver
driver = webdriver.Chrome()
driver.maximize_window()
def login_weibo(username, password):
"""登录微博"""
print("正在打开登录页面...")
driver.get("https://weibo.com/login.php")
try:
# 微博的登录元素可能会变化,这里使用一个常见的定位方式
# 等待用户名输入框出现
username_input = WebDriverWait(driver, 15).until(
EC.presence_of_element_located((By.CSS_SELECTOR, "input[placeholder='手机/邮箱/用户名']"))
)
print("找到用户名输入框。")
# 输入用户名和密码
username_input.send_keys(username)
password_input = driver.find_element(By.CSS_SELECTOR, "input[type='password']")
password_input.send_keys(password)
# 点击登录按钮
login_button = driver.find_element(By.CSS_SELECTOR, "div[node-type='submitBtn']")
login_button.click()
print("点击登录按钮。")
# 登录后需要等待,处理可能出现的滑动验证码
# 注意:Selenium 处理复杂的图形验证码很困难,这里只是演示
# 实际中可能需要人工介入,或者使用打码平台
print("请手动完成登录(如有滑动验证码)...")
time.sleep(20) # 给用户足够的时间手动登录
# 验证是否登录成功:检查页面是否包含退出登录的链接
WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.LINK_TEXT, "退出"))
)
print("登录成功!")
except Exception as e:
print(f"登录过程中出现错误: {e}")
print("可能是元素定位失败,请检查微博登录页的结构是否已更改。")
def get_hot_search():
"""获取微博热搜榜"""
print("正在访问热搜榜...")
driver.get("https://s.weibo.com/top/summary")
try:
# 等待热搜榜列表加载
WebDriverWait(driver, 15).until(
EC.presence_of_element_located((By.CSS_SELECTOR, "table tbody"))
)
# 查找所有热搜条目
# 选择器可能会变,需要实时检查
hot_search_items = driver.find_elements(By.CSS_SELECTOR, "table tbody tr")
print("\n--- 微博热搜榜 TOP 10 ---")
for i, item in enumerate(hot_search_items[:10]):
# 排名
rank_element = item.find_element(By.CSS_SELECTOR, "td.td-01")
rank = rank_element.text
# 标题
title_element = item.find_element(By.CSS_SELECTOR, "td.td-02 a")
title = title_element.text
# 热度
heat_element = item.find_element(By.CSS_SELECTOR, "td.td-02 span")
heat = heat_element.text
print(f"排名: {rank} | 标题: {title} | 热度: {heat}")
except Exception as e:
print(f"获取热搜榜时出现错误: {e}")
if __name__ == "__main__":
# 请替换成你自己的微博账号密码
my_username = "your_username"
my_password = "your_password"
login_weibo(my_username, my_password)
get_hot_search()
# 所有任务完成后关闭浏览器
driver.quit()
进阶技巧与最佳实践
a. 处理 iframe
微博的登录框、评论框等常常嵌套在 <iframe> 中,Selenium 默认不能直接定位 iframe 内部的元素,必须先切换到 iframe。
# 1. 定位到 iframe iframe = driver.find_element(By.ID, "login_frame") # 或其他定位方式 # 2. 切换到 iframe driver.switch_to.frame(iframe) # 3. 现在可以在 iframe 内部定位元素了 username_input = driver.find_element(By.ID, "username") # 4. 操作完成后,切换回主页面(非常重要!) driver.switch_to.default_content()
b. 页面滚动超出视口时,需要手动滚动页面来加载更多内容或定位元素。
# 滚动到页面底部
driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
# 滚动到特定元素
element = driver.find_element(By.ID, "some_element")
driver.execute_script("arguments[0].scrollIntoView();", element)
c. 无头模式
如果你不希望弹出浏览器窗口(例如在服务器上运行),可以使用无头模式。
from selenium.webdriver.chrome.options import Options
chrome_options = Options()
chrome_options.add_argument("--headless") # 启用无头模式
chrome_options.add_argument("--disable-gpu") # 某些系统需要禁用GPU
driver = webdriver.Chrome(options=chrome_options)
d. 使用更强大的定位器:XPath
当 CSS 选择器难以使用时,XPath 是一个强大的替代品。
- 绝对路径:
/html/body/div[1]/div[2]/div[3](不推荐,页面结构一变就失效) - 相对路径:
//div[@class='main']//a[text()='登录'](推荐)- 从任意位置查找
div: 查找div[@class='main']: 筛选class属性为main的div//a: 在该div内查找a[text()='登录']: 筛选文本内容为 "登录" 的a
重要注意事项(防封禁)
使用自动化脚本操作网站,尤其是微博这种对反爬虫非常严格的平台,极易导致账号被限制功能甚至永久封禁,请务必遵守以下原则:
- 控制频率:这是最重要的! 不要让你的脚本以极高的速度(如毫秒级)连续请求,在操作之间加入
time.sleep(random.uniform(2, 5))这样的随机延迟,模拟人类的正常操作节奏。 - 模拟人类行为:除了延迟,还可以模拟鼠标移动、随机滚动页面等,让行为更像真人。
- 使用代理 IP:如果你的 IP 地址被封了,可以切换到其他 IP,可以购买代理 IP 服务,并在 Selenium 中配置。
chrome_options = Options() chrome_options.add_argument('--proxy-server=http://your_proxy_ip:port') driver = webdriver.Chrome(options=chrome_options) - 清理 Cookie:定期清理浏览器的 Cookie,或者每次使用不同的浏览器配置文件(Profile)。
- 尊重
robots.txt:虽然自动化脚本不受robots.txt的法律约束,但它是网站所有者意愿的体现,遵守它是基本的职业道德。 - 不要用于恶意目的:不要用脚本进行恶意刷屏、传播垃圾信息、攻击他人等行为。
- 账号隔离:如果可能,使用专门的“小号”进行自动化测试,避免影响主账号。
希望这份详细的指南能帮助你顺利上手 Python Selenium 微博自动化!祝你编码愉快!
