Редактировать: Обратите внимание, что я использовал класс SoupStrainer, потому что он немного более эффективен (с точки зрения памяти и скорости), если вы заранее знаете, что анализируете.
Ответ 2
Для полноты картины используется версия BeautifulSoup 4, в которой также используется кодировка, предоставляемая сервером:
from bs4 import BeautifulSoup import urllib.request
parser = 'html.parser'# or 'lxml' (preferred) or 'html5lib', if installed resp = urllib.request.urlopen("http://www.gpsbasecamp.com/national-parks") soup = BeautifulSoup(resp, parser, from_encoding=resp.info().get_param('charset'))
for link in soup.find_all('a', href=True): print(link['href'])
или версии Python 2:
from bs4 import BeautifulSoup import urllib2
parser = 'html.parser'# or 'lxml' (preferred) or 'html5lib', if installed resp = urllib2.urlopen("http://www.gpsbasecamp.com/national-parks") soup = BeautifulSoup(resp, parser, from_encoding=resp.info().getparam('charset'))
for link in soup.find_all('a', href=True): print link['href']
и версия, использующая requests библиотеку, которая, как написано, будет работать как на Python 2, так и на Python 3:
from bs4 import BeautifulSoup from bs4.dammit import EncodingDetector import requests
parser = 'html.parser'# or 'lxml' (preferred) or 'html5lib', if installed resp = requests.get("http://www.gpsbasecamp.com/national-parks") http_encoding = resp.encoding if'charset'in resp.headers.get('content-type', '').lower() elseNone html_encoding = EncodingDetector.find_declared_encoding(resp.content, is_html=True) encoding = html_encoding or http_encoding soup = BeautifulSoup(resp.content, parser, from_encoding=encoding)
for link in soup.find_all('a', href=True): print(link['href'])
soup.find_all('a', href=True) Вызов находит все <a> элементы, у которых есть href атрибут; элементы без атрибута пропускаются.
BeautifulSoup 3 прекратил разработку в марте 2012 года; новые проекты действительно должны всегда использовать BeautifulSoup 4.
Обратите внимание, что вам следует оставить декодирование HTML из байтов в BeautifulSoup. Вы можете сообщить BeautifulSoup набор символов, найденный в заголовках HTTP-ответа, чтобы помочь в декодировании, но это может быть неправильным и противоречить <meta> информации заголовка, содержащейся в самом HTML, вот почему в приведенном выше примере используется метод внутреннего класса BeautifulSoup EncodingDetector.find_declared_encoding(), чтобы убедиться, что такие встроенные подсказки по кодировке победят неправильно сконфигурированный сервер.
С помощью requests, response.encoding атрибут по умолчанию имеет значение Latin-1, если в ответе есть text/* mimetype , даже если набор символов не был возвращен. Это согласуется с HTTP RFC, но вызывает неудобства при использовании с синтаксическим анализом HTML, поэтому вам следует игнорировать этот атрибут, если в заголовке Content-Type установлено значение no charset.
Ответ 3
Другие рекомендовали BeautifulSoup, но гораздо лучше использовать lxml. Несмотря на свое название, он также предназначен для синтаксического анализа и очистки HTML. Это намного, намного быстрее, чем BeautifulSoup, и даже обрабатывает "битый" HTML лучше, чем BeautifulSoup (их претензия на известность). Также есть API совместимости для BeautifulSoup, если вы не хотите изучать lxml API.
Больше нет причин использовать BeautifulSoup, если только вы не используете Google App Engine или что-то еще, где запрещено использовать что-либо, кроме Python.
lxml.html также поддерживает селекторы CSS3, так что подобные вещи тривиальны.
Пример с использованием lxml и xpath будет выглядеть следующим образом:
for link in dom.xpath('//a/@href'): # select the url in href for all a tags(links) print link
Ответ 4
import urllib2 import BeautifulSoup
request = urllib2.Request("http://www.gpsbasecamp.com/national-parks") response = urllib2.urlopen(request) soup = BeautifulSoup.BeautifulSoup(response) for a in soup.findAll('a'): if'national-park'in a['href']: print'found a url with national-park in the link'