Python实现周期性抓取网页内容的方法
介绍如何使用Python内置的sched模块实现周期性网页抓取任务。通过自定义回调函数定期请求指定URL,利用正则表达式精准提取目标数据,并将结果按特定格式写入本地文件以供后续图表展示。本文提供完整可运行的代码示例及环境适配说明。
目标原理与环境准备
周期性抓取网页常用于监控指标、统计流量或积累历史数据。Python标准库中的sched模块提供了轻量级的时间调度能力,无需安装第三方依赖即可完成定时触发、任务排队与自循环调度。运行前请确保Python环境为3.x版本(原文示例基于Python 2,已全面迁移至Python 3标准库),并确认目标网址允许自动化访问。
第1步:初始化定时调度器
目的:创建事件队列管理器,定义获取当前时间与阻塞等待的底层实现。
入口:Python脚本头部导入模块。
关键参数:第一个参数传入返回浮点时间戳的函数,第二个参数传入阻塞延时的函数。
完成状态:实例化scheduler对象后,即可调用enter()向队列插入定时任务。
第2步:封装网页请求与数据解析逻辑
目的:定义单次抓取的执行体,包含网络请求、正则匹配与文件落盘。
入口:编写核心回调函数event_func。
动作与参数:使用urllib.request发起GET请求,读取响应正文后解码;通过正则表达式定位目标字段(例如论坛在线人数);提取纯数字后格式化写入本地记录文件。为避免IO堵塞导致调度延迟,建议使用上下文管理器管理文件句柄。
完成状态:控制台打印当前时间与提取数值,工作目录下同步生成包含时间戳与数值的日志文件。
第3步:设置周期循环与异常防护
目的:保证调度器在每次任务结束后自动重新入队,防止进程意外退出导致任务终止。
入口:包装调度入口函数perform与启动函数mymain。
重要参数:enter(interval, priority, function, arguments)中,间隔时间决定抓取频率(单位秒),优先级用于处理并发冲突。推荐加入try...except捕获网络超时或编码错误,确保单次失败不中断整个定时链。
完成状态:调用s.run()后,脚本进入常驻运行状态,控制台周期性输出抓取日志。
第4步:启动服务并核对执行结果
目的:验证调度节奏与数据准确性。
入口:执行脚本主入口。
动作:观察终端输出的时间戳间隔是否与设定的间隔一致;检查生成的liuvUserNum.txt文件内容是否符合预期格式(如供图表库读取的键值对结构)。若发现数据缺失或乱码,需核对目标站点的实际字符集(常见为UTF-8或GBK)并在read().decode()中显式声明编码格式。
import time
import sched
import urllib.request
import re
# 初始化调度器:使用系统时间与时钟阻塞
s = sched.scheduler(time.time, time.sleep)
# 周期性触发的核心采集函数
def event_func():
target_url = 'http://bt.neu6.edu.cn/'
req = urllib.request.Request(target_url)
try:
response = urllib.request.urlopen(req)
rawdata = response.read().decode('utf-8')
response.close()
# 正则匹配:支持前后空白字符的灵活匹配
pattern = re.compile(r'总计\s*<em>(.*?)</em>\s*人在线', re.IGNORECASE)
match = pattern.search(rawdata)
if match:
current_num = match.group(1)
print(f"Current Time: {time.strftime('%Y-%m-%d %H:%M')} User num: {current_num}")
# 安全写入数据文件,格式兼容主流图表工具
with open('liuvUserNum.txt', 'a', encoding='utf-8') as f:
f.write(f"{{year: new Date({time.strftime('%Y,%m,%d,%H,%M')}),value:{current_num}}},\n")
except Exception as e:
print(f"抓取失败: {e}")
finally:
# 任务结束后再次入队,维持周期性执行
s.enter(900, 1, perform, (900,))
def perform(interval_sec):
event_func()
def mymain():
# 初始入队并启动调度引擎
s.enter(0, 1, perform, (900,))
print("定时抓取任务已启动,每900秒执行一次...")
s.run()
if __name__ == '__main__':
mymain()
常见问题排查
- 连接超时或拒绝访问:目标站点可能启用IP频次限制或验证码拦截。可在请求头中添加
User-Agent模拟浏览器,或适当拉长调度间隔。 - 正则匹配结果为空:页面结构动态加载或字符编码不一致会导致匹配失效。建议先用
print(rawdata[:500])打印原始报文,核对标签名称与空格分布后微调正则。 - 进程退出后任务停止:
sched为内存级调度器,不支持跨进程持久化。若需长期后台运行,建议搭配systemd、cron或屏幕会话工具保持驻留。
简要总结
通过sched模块构建的周期性抓取方案具备极低依赖门槛与高可控性。配合正则解析与结构化文件输出,可快速打通从网页数据到可视化报表的数据链路。实际部署时请遵守目标网站的爬取协议,合理控制请求频率。以上就是Python实现周期性抓取网页内容方法的详细内容,更多关于Python定时任务与数据抓取的资料请关注本站其它相关文章!
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













