Python实现周期性抓取网页内容的方法

苏见山
苏见山
发布时间:2026-10-12| 3人浏览过
原创

介绍如何使用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定时任务与数据抓取的资料请关注本站其它相关文章!

相关标签:

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。