I.e. are the different addressing modes encoded somehow in the opcodes? Can they be extracted programmatically or does this info only exist in the documentation of the 6502? I'm writing an emulator and I'm not concerned with performance. It would be nice to have a function that takes an opcode and returns the addressing mode, if possible.
So far I've not come across any indication that there's a pattern in the codes, except that all zero page instructions seem to have their third bit set.
Yes there is. The addressing mode is encoded in 3 bits at positions 4-2 in the opcode byte (i.e. xxxAAAxx). Decoding the addressing mode is dependent on the other bits, but they conform to a regular pattern (mostly) which can be dropped through a lookup table to determine the mode for each instruction type.
This page has a full description of the various patterns and how to decode in each case.