
Selenium 本身并非浏览器,而是一套跨平台、跨浏览器的自动化测试框架,其核心工作流程分为三步:
要实现基于 Selenium 的新闻数据采集,首先需要完成以下环境配置,全程以 Python 语言、Chrome 浏览器为例:
Selenium 操作 Chrome 浏览器必须依赖 ChromeDriver,关键注意点:ChromeDriver 版本必须与本地安装的 Chrome 浏览器版本对应。
打开 Chrome 浏览器 → 点击右上角「三个点」→ 「帮助」→ 「关于 Google Chrome」,查看当前浏览器版本(如 120.0.6099.109)。
两种配置方式二选一即可:
本次实战以某资讯网站的国内新闻栏目为例,实现以下功能:1. 打开目标网站,等待页面完全加载;2. 提取单页新闻的标题、发布时间、链接、摘要;3. 模拟点击翻页,批量采集多页数据;4. 将采集到的数据保存为 Excel 文件,方便后续分析。
python
运行
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import NoSuchElementException, TimeoutException
import pandas as pd
import time
class NewsCrawler:
def __init__(self):
# 初始化Chrome浏览器配置
self.options = webdriver.ChromeOptions()
# 可选配置:隐藏浏览器窗口(无头模式),提升采集效率
# self.options.add_argument('--headless=new')
# 可选配置:禁用图片加载,减少页面加载时间
self.options.add_argument('--blink-settings=imagesEnabled=false')
# 可选配置:模拟普通浏览器请求,避免被反爬识别
self.options.add_argument('user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36')
# 初始化浏览器驱动
self.driver = webdriver.Chrome(options=self.options)
# 初始化WebDriverWait,设置默认最大等待时间10秒
self.wait = WebDriverWait(self.driver, 10)
# 初始化新闻数据存储列表
self.news_data = []
def extract_news_single_page(self):
"""提取单页的所有新闻数据"""
try:
# 显式等待:等待新闻列表容器加载完成(根据目标网站调整元素定位器)
news_list = self.wait.until(
EC.presence_of_all_elements_located(
(By.CLASS_NAME, "news-item") # 替换为目标网站的新闻项类名
)
)
# 遍历新闻列表,提取单条新闻数据
for news in news_list:
news_info = {}
try:
# 提取新闻标题(根据目标网站调整元素定位方式)
title_elem = news.find_element(By.CLASS_NAME, "news-title")
news_info["标题"] = title_elem.text
news_info["链接"] = title_elem.get_attribute("href")
# 提取新闻发布时间
time_elem = news.find_element(By.CLASS_NAME, "news-time")
news_info["发布时间"] = time_elem.text
# 提取新闻摘要
summary_elem = news.find_element(By.CLASS_NAME, "news-summary")
news_info["摘要"] = summary_elem.text
# 将单条新闻数据添加到总列表
self.news_data.append(news_info)
print(f"成功提取新闻:{news_info['标题']}")
except NoSuchElementException as e:
print(f"单条新闻数据提取失败,缺失元素:{str(e)}")
continue
print(f"当前页面提取完成,累计采集新闻{len(self.news_data)}条")
except TimeoutException:
print("新闻列表加载超时,无法提取单页数据")
except Exception as e:
print(f"单页数据提取异常:{str(e)}")
def click_next_page(self):
"""模拟点击下一页按钮,返回是否成功翻页"""
try:
# 显式等待:等待下一页按钮可点击
next_btn = self.wait.until(
EC.element_to_be_clickable(
(By.CLASS_NAME, "page-next") # 替换为目标网站的下一页按钮类名
)
)
# 模拟点击下一页(避免直接点击触发反爬,添加短暂延时)
self.driver.execute_script("arguments[0].click();", next_btn)
# 翻页后等待新页面加载(可根据网站加载速度调整延时)
time.sleep(2)
return True
except (NoSuchElementException, TimeoutException):
print("已无下一页,翻页结束")
return False
except Exception as e:
print(f"翻页操作异常:{str(e)}")
return False
def batch_crawl_news(self, target_url, page_count=5):
"""
批量采集多页新闻数据
:param target_url: 目标新闻栏目URL
:param page_count: 要采集的页数,默认5页
"""
try:
# 打开目标网站
self.driver.get(target_url)
print(f"成功打开目标网站:{target_url}")
# 循环采集指定页数
for current_page in range(1, page_count + 1):
print(f"\n开始采集第{current_page}页新闻数据")
# 提取当前页新闻数据
self.extract_news_single_page()
# 翻页(如果是最后一页,无需翻页)
if current_page < page_count:
if not self.click_next_page():
break
except Exception as e:
print(f"批量采集异常:{str(e)}")
def save_news_to_excel(self, file_name="新闻采集结果.xlsx"):
"""将采集到的新闻数据保存为Excel文件"""
if not self.news_data:
print("无采集到的新闻数据,无法保存")
return
try:
# 将列表转换为pandas DataFrame
df = pd.DataFrame(self.news_data)
# 保存为Excel文件(忽略索引列)
df.to_excel(file_name, index=False, engine="openpyxl")
print(f"新闻数据已成功保存为Excel文件,路径:{file_name}")
print(f"最终采集到有效新闻{len(self.news_data)}条")
except Exception as e:
print(f"数据保存失败:{str(e)}")
def close_crawler(self):
"""关闭浏览器,释放资源"""
self.driver.quit()
print("爬虫已关闭,浏览器资源释放完成")
# 主函数:执行新闻采集
if __name__ == "__main__":
# 初始化爬虫实例
news_crawler = NewsCrawler()
try:
# 配置目标参数(替换为实际的新闻栏目URL)
TARGET_NEWS_URL = "https://www.example.com/news/domestic" # 示例URL,需替换为真实地址
CRAWL_PAGE_COUNT = 5 # 要采集的页数
# 批量采集新闻数据
news_crawler.batch_crawl_news(TARGET_NEWS_URL, CRAWL_PAGE_COUNT)
# 保存采集结果到Excel
news_crawler.save_news_to_excel()
finally:
# 无论采集是否成功,最终都关闭爬虫
news_crawler.close_crawler()代码中使用By.CLASS_NAME进行元素定位(如news-item、news-title),这是最常用的定位方式之一。实际使用时,需要根据目标新闻网站的 HTML 结构,替换为对应的定位器,常用定位方式包括:
By.ID:通过元素 ID 定位(优先级最高,唯一性最强);By.XPATH:通过 XPath 路径定位(最灵活,支持复杂场景,如//div[@class="news-item"]/h3/a);By.CSS_SELECTOR:通过 CSS 选择器定位(效率高,如.news-item .news-title);By.TAG_NAME:通过标签名定位(适用于批量获取同类型标签)。WebDriverWait配合expected_conditions,等待关键元素加载完成后再执行操作,避免 “元素未找到” 的错误,相比time.sleep()的固定延时,更灵活、更高效;execute_script()点击避免元素遮挡导致的点击失败,翻页后添加短暂延时,确保新页面完全加载;pandas将采集到的列表数据转换为 Excel 文件,方便后续的数据分析和整理。代码中提供了无头模式(隐藏浏览器窗口)的配置,注释解除后即可启用,适合在服务器端运行,提升采集效率;如果采集过程中出现页面加载缓慢,可适当调整WebDriverWait的最大等待时间和time.sleep()的延时时间。
在实际的新闻采集场景中,面对高强度反爬的新闻网站,单纯的基础采集脚本可能会出现被封禁、采集效率低下等问题,以下是几种关键的优化策略:
requests库或专业代理 IP 服务(例如亿牛云),在ChromeOptions中添加代理配置:self.options.add_argument('--proxy-server=http://ip:port');time.sleep(random.uniform(1, 3))),模拟真人的操作节奏,避免固定操作间隔被反爬识别;ddddocr(验证码识别库)、Selenium模拟滑块拖动等方式,实现验证码自动处理;self.driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")),实现无限滚动采集。Selenium 凭借其强大的浏览器模拟能力和动态页面解析能力,完美解决了传统爬虫在新闻数据批量采集中遇到的动态渲染、反爬拦截等难题。本文从环境搭建、实战实现到进阶优化,全面讲解了基于 Selenium 的新闻采集流程,核心要点总结如下:
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。