NaiboWang/EasySpider · warning · Exception

dont parse timezone format

Error message

dont parse timezone format

What it means

Raised by TimeUtil.convert_timezone in Examples/.../author_crawl.py:51 when the parsed timezone symbol is neither '+' nor '-'. In the shipped code this branch is effectively UNREACHABLE: parse_timezone uses the regex (?P<symbol>[+-])(?P<offset>\d+) which only ever captures '+' or '-'. A genuinely malformed timezone string (e.g. 'UTC', '8', '') instead makes re.match return None, so result.groupdict() throws AttributeError before convert_timezone reaches the symbol check. Hitting THIS exact message implies parse_timezone was modified to emit a non +/- symbol.

Source

Thrown at Examples/Sample Tasks with Python/author_crawl.py:51

        return {
            'symbol': symbol,
            'offset': offset
        }

    @classmethod
    def convert_timezone(cls, dt, timezone="+0"):
        """默认是utc时间,需要"""
        result = cls.parse_timezone(timezone)
        symbol = result['symbol']

        offset = result['offset']

        if symbol == '+':
            return dt + timedelta(hours=offset)
        elif symbol == '-':
            return dt - timedelta(hours=offset)
        else:
            raise Exception('dont parse timezone format')


def generate_timestamp():
    current_GMT = time.gmtime()
    # ts stores timestamp
    ts = calendar.timegm(current_GMT)

    current_time = datetime.utcnow()
    convert_now = TimeUtil.convert_timezone(current_time, '+8')
    print("current_time:    " + str(convert_now))
    return str(convert_now)


def main():
    # result = os.popen('python ServiceWrapper_ExecuteStage.py 38')
    # res = result.read()
    # for line in res.splitlines():
    #     print("\n\n\n\nfinename:\n\n\n\n\n", line)

View on GitHub (pinned to 191bd6d754)

Solutions

  1. Validate the timezone string against ^[+-]\d+$ before calling convert_timezone.
  2. Fix parse_timezone to handle a no-match: if not result: raise ValueError(f'invalid timezone: {timezone!r}').
  3. Replace the generic Exception with ValueError and cover the real failure (None match) instead of the dead else.

Example fix

# before
result = re.match(r'(?P<symbol>[+-])(?P<offset>\d+)', timezone)
symbol = result.groupdict()['symbol']  # AttributeError if no match

# after
result = re.match(r'(?P<symbol>[+-])(?P<offset>\d+)', timezone)
if not result:
    raise ValueError(f'invalid timezone format: {timezone!r}')
symbol = result.group('symbol')
offset = int(result.group('offset'))
Defensive patterns

Strategy: validation

Validate before calling

import re
if not re.match(r'^[+-]\d+$', timezone or ''):
    raise ValueError(f'timezone must look like +8 / -5, got {timezone!r}')

Prevention

When it happens

Trigger: TimeUtil.convert_timezone(dt, timezone) calls cls.parse_timezone(timezone); if a future/modified parse_timezone returns {'symbol': <not +/->, ...}, the if/elif chain falls through to raise Exception('dont parse timezone format').

Common situations: The sample is copy-pasted and parse_timezone is edited to support named zones; or timezone comes from external config that bypasses the regex; or a monkeypatch returns a symbol the if-chain does not recognize. The far more common real-world failure from bad input is AttributeError: 'NoneType' object has no attribute 'groupdict', not this message.

Related errors


AI-assisted analysis of NaiboWang/EasySpider@191bd6d754 (2026-08-13). Data as JSON: /api/errors/71c9f5db62cdb0b4. Report an issue: GitHub.