遍历文件多行执行正则匹配时仅最后一行正常,其余报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实体转义坑了你
你的示例正则用了<和>(也就是HTML实体的<和>),但实际页面里的标签是真实的<dd class="MetadataCard-content">,这时候正则肯定匹配不到。
修复办法:
在使用正则前,把实体转成真实的标签字符:
regex_str = regex_str.replace('<', '<').replace('>', '>')
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('<', '<').replace('>', '>') 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
相关产品推荐
相关产品推荐

