Видеокурс выложен на сайте Altube.ru вместо Youtube и плеер Altube не поддерживает субтитры. Прошу решить вопрос о предоставлении русских субтитров в этом англоязычном видеокурсе. |
Сетевые программы
23.6. Разбор HTML-страниц с помощью библиотеки BeautifulSoup
В Питоне есть несколько библиотек, помогающих при разборе HTML-текста и извлечении данных из веб-страниц. Каждая из этих библиотек имеет свои преимущества и недостатки.
Вы можете выбрать одну из них, основываясь на своих потребностях. Например, задача разбора HTML-текста и извлечения ссылок из него легко решается с помощью библиотеки BeautifulSoup. Вы можете скачать и установить эту библиотеку с адреса http://www.crummy.com. Можно даже не устанавливая библиотеку, просто поместить файл BeautifulSoup.py в тот же каталог, что и ваше приложение.
Несмотря на то, что HTML-документ выглядит как XML и некоторые страницы тщательно сконструированы так, чтобы удовлетворять строгим правилам XML, большая часть HTML-страниц сформирована неправильно в том смысле, что XML-парсер отвергает подобные страницы целиком как некорректные. Но библиотека BeautifulSoup терпимо относится даже к очень неряшливым страницам и позволяет извлекать из них нужную информацию.
Мы будем использовать библиотеку urllib, чтобы читать веб-страницы, и затем библиотеку BeautifulSoup, чтобы извлекать тексты ссылок (т.е. аттрибут href) из тегов <a> (anchor).
import urllib from BeautifulSoup import * url = raw_input('Enter - ') html = urllib.urlopen(url).read() soup = BeautifulSoup(html) # Retrieve all of the anchor tags tags = soup('a') for tag in tags: print tag.get('href', None)
Программа предлагает ввести веб-адрес, открывает веб-страницу, читает ее содержимое и передает данные парсеру BeautifulSoup, а затем извлекает все теги <a> и выводит атрибут href (т.е. гипертекстовую ссылку) для каждого тега.
После запуска программы на выходе получим:
python urllinks.py Enter - http://www.dr-chuck.com/page1.htm http://www.dr-chuck.com/page2.htm python urllinks.py Enter - http://www.py4inf.com/book.htm http://www.greenteapress.com/thinkpython/thinkpython.html http://allendowney.com/ http://www.si502.com/ http://www.lib.umich.edu/espresso-book-machine http://www.py4inf.com/code http://www.pythonlearn.com/
Можно использовать BeautifulSoup для извлечения различных частей каждого тега, как в следующей программе:
import urllib from BeautifulSoup import * url = raw_input('Enter - ') html = urllib.urlopen(url).read() soup = BeautifulSoup(html) # Retrieve all of the anchor tags tags = soup('a') for tag in tags: # Look at the parts of a tag print 'TAG:',tag print 'URL:',tag.get('href', None) print 'Content:',tag.contents[0] print 'Attrs:',tag.attrs
В результате получаем:
python urllink2.py Enter - http://www.dr-chuck.com/page1.htm TAG: <a href="http://www.dr-chuck.com/page2.htm"> Second Page</a> URL: http://www.dr-chuck.com/page2.htm Content: [u'\nSecond Page'] Attrs: [(u'href', u'http://www.dr-chuck.com/page2.htm')]
Эти примеры лишь отчасти демонстрируют силу библиотеки BeautifulSoup в применении к разбору HTML-гипертекста. Для более детального знакомства см. документацию и примеры по адресу .
23.7. Чтение бинарных файлов с помощью urllib
Часто нужно получить из сети нетекстовый (бинарный) файл, например, изображение или видео-файл. Данные в таких файлах обычно не используются для печати, но с помощью urllib нетрудно просто скопировать содержимое сетевого файла на жесткий диск.
Открываем URL и используем метод read для скачивания всего содержимого документа в строковую переменную img, затем записываем эту информацию в локальный файл:
img = urllib.urlopen('http://www.py4inf.com/cover.jpg').read() fhand = open('cover.jpg', 'w') fhand.write(img) fhand.close()
Эта программа читает по сети все данные целиком и сохраняет их в переменной img, содержащейся в оперативной памяти компьютера, затем открывает файл cover.jpg и записывает данные на диск.
Это работает, когда размер сетевого файла меньше, чем объем памяти вашего компьютера. Однако при чтении огромного аудио- или видео-файла программа может привести к отказу или в лучшем случае начнет работать крайне медленно, когда физическая память компьютера будет исчерпана.
Чтобы избежать подобной ситуации, мы читаем данные из сети блоками и записываем каждый блок на диск перед тем, как считать следующий блок. При подобном способе работы программа может прочитать сетевой файл любого размера и при этом избежать переполнения памяти компьютера.
import urllib img = urllib.urlopen('http://www.py4inf.com/cover.jpg') fhand = open('cover.jpg', 'w') size = 0 while True: info = img.read(100000) if len(info) < 1 : break size = size + len(info) fhand.write(info) print size,'characters copied.' fhand.close()
В этом примере мы читаем за один раз блок размером в 100000 байтов и записываем его файл cover.jpg перед чтением следующей порции данных из сети. После запуска программа выдает:
python curl2.py 568248 characters copied.
Если у вас Unix- или Macintosh-компьютер, то, скорее всего, в операционной системе есть команда, которая выполняет описанную выше операцию:
curl -O http://www.py4inf.com/cover.jpg
Название команды curl является сокращением от "copy URL". Поэтому файлы с программами Питона из последних двух примеров называны curl1.py и curl2.py – они делают то же самое, что и команда curl. Также имеется программа curl3.py, которая решает ту же задачу чуть более эффективно – ее тоже можно использовать в качестве образца при написании собственных программ.