Why would you want to do explicit page level locking? You don't control what is on each page, so you'd be locking some arbitrary collection of data. What purpose would that serve?
I think you're looking for row-level locking, which is accomplished using
SELECT ... FOR UPDATE or
SELECT ... FOR SHARE.
PostgreSQL upgrades row-level locks to page-level locks internally in a few places like serializable snapshot predicate tracking, buffer management, etc. It'll do this when there are too many row level locks and they're becoming a performance issue. You don't need to care about this, as this will have almost no effect on you at the SQL level. Normal row locks - as acquired by
SELECT ... FOR UPDATE,
SELECT ... FOR SHARE etc - are AFAIK never upgraded to page-level locks, as doing so would increase the probability of deadlocks.
If you're really convinced you want page-level locking, please explain what problem you're trying to solve in more detail and why row-level or table-level locking don't do the job.