Молодогвардейцев 454015 Россия, Челябинская область, город Челябинск 89085842764
MindHalls logo

Чтение веб-страницы с помощью Python

Доброго времени суток! Для начала у меня появился вот такой вопросик. Можно ли считать программную обработку содержимого html старничек веб-программированием? Вроде в вебе работаем, имеем дело с сетевыми протоколами и все такое. Кто точно знает ответ на этот вопрос, поделитесь в комментариях, я буду признателен.

Но перейдем к делу. Недавно в университете нам выдали интересное задание, связанное с чтением веб-страниц с помощью Pythonна. Научитесь, говорят, считывать страницы. Насколько я знаю, это весьма нетривиальная задача для решения на C/C++. Но чего только нет в стандартной библиотеке Python. Оказывается, существует специальный модуль urllib для работы с урлами. Замечательно! Даже искать не пришлось. Пара слов о том, какие функции мне понадобились из этого модуля.

Как прочитать веб-страницу с помощью Python

Будем пользоваться модулем под названием request, который входит в состав упомянутого выше urllib. И более того, используем всего лишь одну единственную и жутко простую функцию urlopen. Из названия нетрудно догадаться, чем она занимается.

В случае, когда схема ulrа имеет тип file(например урлы файлов в локальной сети), создастся идентификатор этого файла, как при обычном вызове open. Если же ссылка ведет в сеть, страничка будет загружена, считана и нам вернется файло-подобный индентификатор, для которого доступны все любимые нами методы. Такие, как read(), readlines(), close(), info() и некоторые другие.

Питон тем и крут, что можно особо не заморачиваться над тем, как это работает и читать ссылку, как обычный файл. Отличие только в том, что html страница всегда читается в виде массива байт. Это значит, что для удобства обработки, строки нужно декодировать в utf-8 с помощью метода decode(‘utf-8’).

Пример использования

Задача состоит в том, чтобы вытащить с сайта математического факультета список всех сотрудников и их контактные данные. Поиграем немного в  шпионов? Шутка, данные ведь общедоступные. Да и реализация мягко говоря не тянет на секретный алгоритм слежки. Потому что я писал конкретно разбор этого сайта, учитывая структуру его html документов.

Исходный код решения


import urllib.request

#url, на котором находится список преподователей
link = urllib.request.urlopen('http://math.csu.ru/index.php?option=com_content&view=article&id=56&Itemid=70')

lines = []
for line in link.readlines():
    #взяли все строки с сотрудниками
    #Каждый сотрудник начинается с тегов <li><a href .....
    if line.find(b'<li>') != -1 and line.find(b'a href') != -1:
        lines.append(line)

link.close()

#Переводим bytes в str
for i in range(len(lines)):
    lines[i] = lines[i].decode('utf-8')

#Можно работать как с обычной строкой
for i in range(len(lines)):
    #Убираем все лишнее
    lines[i] = lines[i].replace('\t\t\t<li>', '')
    lines[i] = lines[i].replace('\"', '')
    lines[i] = lines[i].replace('<a href=', '')
    lines[i] = lines[i].replace('target=_blank>', '')
    lines[i] = lines[i].replace('</a></li>', '')
    lines[i] = lines[i].replace('</ul>', '')
    lines[i] = lines[i].replace("\r\n", '')

#Фио сотрудников
names = []
#URL`ы с их контактными данными
urls = []
for line in lines:
    words = line.split(' ')
    urls.append(words[0])
    name = words[1] + ' ' + words[2] + ' ' + words[3]
    names.append(name)

#Теперь нужно сходить на ссылку каждого и вытащить контактные данные
contacts = []
for url in urls:
    link = urllib.request.urlopen(url)

    #Данные лежат в <div class="fields ContactInfo">
    for line in link.readlines():
        pos = line.find(b'<div class="fields ContactInfo')
        if pos != -1:
            line = line[pos:]
            #С этого тега заканчивается слово "Контактные данные:" и начинаются сами данные
            start = line.find(b'</b>')
            #Сразу после контактов закрывается тег div
            end = line.find(b'</div>')

            contacts.append(line[start + len(b'</b>') : end].decode('utf-8'))

            break

    link.close()

for i in range(len(names)):
    print(names[i], ' : ', contacts[i])

Заключение

Тут и добавить особо нечего, читать ссылки, как обычные файлы это очень круто. Можно научиться поднимать свой локальный сервер и делать из него агрегатор статей с новостных сайтов. А можно раскачаться окончательно и написать свой аналог google translate. Но это оставим на потом, спасибо за внимание!

  • sergovoy

    Здорово!
    Проверил у себя — прекрасно работает Ваш код)