How do I determine whether an input or output is segwit? I'm trying to go through the transactions in a block and determine how many segwit inputs or outputs there are.

I've noticed in getrawtransaction that segwit inputs seem to have a 'txinwitness' field. Is that a good way to classify them?

For outputs I know I can't just look at the 3* address because not all p2sh are segwit. So what's the best way there?

EDIT:
I just found this page about 3* addresses. Difference between a SegWit address and a P2SH address

Am I correct in interpreting this to say that you can't determine whether an output is segwit? Only an input?
I'm trying to go through the transactions in a block and determine how
  many segwit inputs or outputs there are.


BIP141 defines a segwit tx marker and a flag at the beginning of a transaction. So if you decompose such a tx, you would see with the flag, if there is SegWit:

raw tx is: ### raw tx is this:
01000000000102FFF7F7881A8099AFA6940D42D1E7F6362BEC38171EA3EDF433541DB4E4AD969F000000004948
30450221008B9D1DC26BA6A9CB62127B02742FA9D754CD3BEBF337F7A55D114C8E5CDD30BE022040529B194BA3
F9281A99F2B1C0A19C0489BC22EDE944CCF4ECBAB4CC618EF3ED01EEFFFFFFEF51E1B804CC89D182D279655C3A
A89E815B1B309FE287D9B2B55D57B90EC68A0100000000FFFFFFFF02202CB206000000001976A9148280B37DF3
78DB99F66F85C95A783A76AC7A6D5988AC9093510D000000001976A9143BDE42DBEE7E4DBE6A21B2D50CE2F016
7FAA815988AC000247304402203609E17B84F6A7D30C80BFA610B5B4542F32A8A0D5447A12FB1366D7F01CC44A
0220573A954C4518331561406F90300E8F3358F51928D43C212A8CAED02DE67EEBEE0121025476C2E83188368D
A1FF3E292E7ACAFCDB3566BB0AD253F62FC70F07AEEE635711000000


VERSION
 01000000

SEGWIT (BIP141): this is a segwit tx, marker=00
       (BIP141): flag=01

TX_IN COUNT [var_int]: hex=02, decimal=2
 TX_IN[0]
  TX_IN[0]       9F96ADE4B41D5433F4EDA31E1738EC2B36F6E7D1420D94A6AF99801A88F7F7FF
  TX_IN[0] hex=00000000, reversed=00000000, decimal=0
  TX_IN[0] Script Length hex=49, decimal=73
  TX_IN[0] Script Sig 4830450221008B9D1DC26BA6A9CB62127B02742FA9D754CD3BEBF337F7A55D114C8E5CDD30BE022040529B19
4BA3F9281A99F2B1C0A19C0489BC22EDE944CCF4ECBAB4CC618EF3ED01 
  TX_IN[0] Sequence (uint32_t)
  EEFFFFFF
 TX_IN[1]
  TX_IN[1] 8AC60EB9575DB5B2D987E29F301B5B819EA83A5C6579D282D189CC04B8E151EF
  TX_IN[1] OutPoint index hex=01000000, reversed=00000001, decimal=1
  TX_IN[1] Script Length hex=00, decimal=0
  TX_IN[1] Sequence FFFFFFFF

TX_OUT COUNT, hex=02, decimal=2
 TX_OUT[0]
 ...

WITNESS TXIN[0] stack elements: hex=00, decimal=0
WITNESS TXIN[1] stack elements: hex=02, decimal=2
 WITNESS data[0]:
  47304402203609E17B84F6A7D30C80BFA610B5B4542F32A8A0D5447A12FB1366D7F01CC44A0220573A954C4518331561406F90300E8F3358F51928D43C212A8CAED02DE67EEBEE01
 WITNESS data[1]:
  21025476C2E83188368DA1FF3E292E7ACAFCDB3566BB0AD253F62FC70F07AEEE6357

 LOCK_TIME
11000000


As this is a tx with two inputs, the first input is non segwit (hence a signature in the V_IN part), the second input is segwit (Script Length = 0), and the witness for second input is added at the end of the tx. 


  Am I correct in interpreting this to say that you can't determine
  whether an output is segwit? Only an input?


With P2SH, you take an original set of data, and run it through a hash function. As the hash function is not reversible (to today's knowledge), you cannot know, what is inside a P2SH. Usual use cases are for example multisig transactions. But it can be other things as well, and only if the spending transaction is in the blockchain, you can see, what was previously inside. So this adds a certain layer of privacy for the time between funding the tx and spending the tx.