Опубликован: 14.06.2015 | Доступ: свободный | Студентов: 4653 / 500 | Длительность: 21:48:00
Авторские права: Creative Commons Attribution 3.0
Лекция 12:

Сетевые программы

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, которая решает ту же задачу чуть более эффективно – ее тоже можно использовать в качестве образца при написании собственных программ.

Ксения Шошина
Ксения Шошина

курс Программирование на Python

Илья Кизилов
Илья Кизилов

В лекции приводится программа для сортировки слов по их длинне. В коде ошибка. Я исправил так:

def sort_by_length(words):

words = words.split()

t = []

for word in words:

t.append((len(word), word))

t.sort(reverse=True)

res = []

for length, word in t:

res.append(word)

return res

print(sort_by_length(words))

 

Кто ещё как сделал?

 

Екатерина Малкова
Екатерина Малкова
Россия, г. Москва