Python爬虫时区转换问题:f-string索引匹配失效求助
问题原因分析
1. 循环索引误用导致f-string匹配失效
你写的for i in range(len(times))里的i是列表的索引(0、1、2...),根本不是时间文本里的小时数值。比如循环到i=0时,代码会找"0:",但网页返回的时间是"00:00"这种两位数的小时格式,自然匹配不上,所以if判断触发不了。去掉冒号后匹配"0",会把文本里所有0都替换,这显然不是你要的效果。
2. 硬编码方案的弊端
硬编码逐个替换小时虽然能运行,但代码冗余度极高,一旦时区偏移量改变(比如夏令时调整),要修改十几行判断逻辑,维护成本非常高。
更优的时区转换解决方案
正确的思路是将时间字符串解析为datetime对象,通过专业时区工具处理后再转回字符串,彻底避开字符串替换的各种坑。具体实现如下:
核心思路
- 用正则表达式提取时间文本中的日期/时间片段
- 将提取到的时间转换为带UTC时区的datetime对象(该网站返回的是UTC时间)
- 转换为你的本地时区
- 将转换后的时间格式化,替换回原文本
完整代码
import requests from bs4 import BeautifulSoup from datetime import datetime import pytz import re # 存储数据的列表 maps = [] times = [] # 爬取目标页面 URL = "https://apexlegendsstatus.com/current-map/battle_royale/pubs" page = requests.get(URL) soup = BeautifulSoup(page.content, "html.parser") # 提取地图名称 for h3_tag in soup.find_all('h3'): maps.append(h3_tag.text) # 提取时间并清理无效项(替代多次pop操作,更简洁) for p_tag in soup.find_all('p'): times.append(p_tag.text) times = times[1:-2] # 定义时区:网站使用UTC,替换为你的本地时区,比如"America/New_York" utc_timezone = pytz.utc local_timezone = pytz.timezone('Asia/Shanghai') # 正则匹配时间格式:支持完整日期(YYYY-MM-DD HH:MM)或仅小时分钟(HH:MM) time_regex = re.compile(r'(\d{4}-\d{2}-\d{2} \d{2}:\d{2}|\d{2}:\d{2})') def fix_timezone(time_text): # 找出文本中所有时间片段 time_matches = time_regex.findall(time_text) for match in time_matches: # 处理两种时间格式 if len(match) == 5: # 仅HH:MM格式,拼接当天UTC日期 utc_today = datetime.now(utc_timezone).strftime("%Y-%m-%d") full_utc_time = f"{utc_today} {match}" utc_datetime = datetime.strptime(full_utc_time, "%Y-%m-%d %H:%M").replace(tzinfo=utc_timezone) else: # 完整日期时间格式 utc_datetime = datetime.strptime(match, "%Y-%m-%d %H:%M").replace(tzinfo=utc_timezone) # 转换为本地时区 local_datetime = utc_datetime.astimezone(local_timezone) # 按原格式输出转换后的时间 formatted_time = local_datetime.strftime("%H:%M") if len(match) ==5 else local_datetime.strftime("%Y-%m-%d %H:%M") # 替换原文本中的时间 time_text = time_text.replace(match, formatted_time) # 修复语法错误 if "starts in 1 hours" in time_text: time_text = time_text.replace("starts in 1 hours", "starts in 1 hour") return time_text # 批量处理所有时间数据 times = [fix_timezone(t) for t in times] # 输出前3组地图与时间信息 for map_name, time_info in zip(maps[:3], times[:3]): print(f"\n{map_name}") print(f"{time_info}\n")
方案优势
- 精准可靠:通过datetime和时区库处理,不会出现误替换数字的情况
- 扩展性强:只需修改
local_timezone的值即可切换时区,自动适配夏令时等时区变化 - 代码简洁:用正则和列表推导式简化逻辑,可读性与维护性远高于硬编码
注意事项
- 需先安装
pytz库:pip install pytz - 确认网站返回的时间时区(该网站为UTC,若后续网站时区变更,调整
utc_timezone即可) - 若网站返回的时间格式发生变化,微调正则表达式即可适配
内容的提问来源于stack exchange,提问作者Frank Theren
相关产品推荐
相关产品推荐

