You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

遍历文件多行执行正则匹配时仅最后一行正常,其余报AttributeError

解决多行文件处理时仅最后一行生效的问题

看起来你的代码在处理单行文件时完全没问题,但一碰到多行就掉链子——前面的行全报AttributeError: 'NoneType' object has no attribute 'group'。本质上这个错误是说这些行的正则匹配返回了None,要么是请求到的页面内容不对,要么就是正则压根没找到目标元素。我来帮你拆解最可能的原因和对应的修复办法:

最可能的几个原因及修复步骤

1. 连续请求被网站拦截了

很多网站会限制频繁的自动请求,单行时只发一次请求没问题,但多行连续请求就会被返回空白页、403页面,自然匹配不到你要的内容。

修复办法:

  • 给请求加间隔,比如每次请求后睡1秒:先导入from time import sleep,然后在requests.get前加sleep(1)
  • 模拟浏览器请求头,避免被识别为爬虫:
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36'
    }
    response = requests.get(url, headers=headers)
    

2. 正则里的HTML实体转义坑了你

你的示例正则用了&lt;和&gt;(也就是HTML实体的<和>),但实际页面里的标签是真实的<dd class="MetadataCard-content">,这时候正则肯定匹配不到。

修复办法:
在使用正则前,把实体转成真实的标签字符:

regex_str = regex_str.replace('&lt;', '<').replace('&gt;', '>')

3. 行内容的格式或分割出了问题

有些行可能存在多余的空格、换行符,或者分隔符::前后带空格,导致分割后拿到的正则字符串带了多余空格,自然匹配失败。

修复办法:
分割时先清理每个部分的空格,同时校验行格式:

parts = [p.strip() for p in line.strip().split('::')]
if len(parts) != 3:
    print(f"跳过格式错误的行:{line}")
    continue
name, url, regex_str = parts

4. 部分页面的结构和示例不一样

不是所有URL对应的页面都和你示例的Firefox插件页结构相同,比如有些页面里根本没有<dd class="MetadataCard-content">这个标签,正则当然匹配不到。

修复办法:
添加调试输出,查看请求到的页面内容,再调整正则:

if not match:
    print(f"{name} 未匹配到内容,页面前500字符预览:")
    print(response.text[:500])

根据实际页面的HTML结构修改对应的正则表达式。

整合后的完整示例代码

import re
import requests
from time import sleep

# 模拟浏览器请求头,避免被拦截
headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36'
}

with open('your_file.txt', 'r', encoding='utf-8') as f:
    # 过滤空行并清理每行的首尾空格
    lines = [line.strip() for line in f if line.strip()]

for line_num, line in enumerate(lines, 1):
    try:
        # 分割行内容并清理每个部分的空格
        parts = [p.strip() for p in line.split('::')]
        if len(parts) != 3:
            print(f"第{line_num}行格式错误,跳过:{line}")
            continue
        
        name, url, regex_str = parts
        
        # 避免请求太频繁被网站拦截
        sleep(1)
        response = requests.get(url, headers=headers)
        # 检查请求是否成功(404、500这类错误会直接抛出异常)
        response.raise_for_status()
        
        # 转换HTML实体为真实的标签字符
        regex_str = regex_str.replace('&lt;', '<').replace('&gt;', '>')
        
        match = re.search(regex_str, response.text)
        if match:
            print(f"✅ {name} 匹配结果:{match.group(1)}")
        else:
            print(f"❌ {name} 未找到匹配内容,正则:{regex_str}")
            # 可选:输出页面片段用于调试
            # print(f"页面预览:{response.text[:500]}")
            
    except Exception as e:
        print(f"⚠️ 处理第{line_num}行时出错:{line}")
        print(f"错误详情:{str(e)}")

这个代码加了错误处理、请求防拦截、格式校验,能帮你精准定位到底是哪一步出了问题,再也不会只跑最后一行啦~

内容的提问来源于stack exchange,提问作者Milton Cardoso

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 08:03:10