Как считают другие, если производительность в режиме реального времени не требуется, BeautifulSoup - хорошее решение:
import urllib2
from BeautifulSoup import BeautifulSoup
html = urllib2.urlopen("http://www.google.com").read()
soup = BeautifulSoup(html)
all_links = soup.findAll("a")
Что касается второго вопроса, да, ссылки HTML должны быть четко определены, но HTML, с которым вы фактически сталкиваетесь, вряд ли будет стандартным. Прелесть BeautifulSoup в том, что он использует браузерную эвристику, чтобы попытаться проанализировать нестандартный искаженный HTML, с которым вы, вероятно, столкнетесь.
Если вы уверены, что работаете со стандартным XHTML, вы можете использовать (намного) более быстрые парсеры XML, такие как expat.
Regex, по вышеуказанным причинам (синтаксический анализатор должен поддерживать состояние, а regex не может этого сделать) никогда не будет общим решением.