Friday, January 27, 2012

Варим суп или как парсить HTML на Python http://silentsokolov.tumblr.com/post/1115124081/html-python

http://silentsokolov.tumblr.com/post/1115124081/html-python

Варим суп или как парсить HTML на Python

Собственно, если кто не в курсе довожу до сведения, что помимо работы, хобби (в виде стартапов), параллельно занимаюсь программированием на замечательном языке Python. Сказать, что я чисто программист не могу, так как в большинстве случаях еще изучаю язык, но решать повседневные "серверные" и линукс задачки не составляет труда.

Так, вот, взбрела мне в голову проблема о парсинге некой страничке в интернете, почему это произошло описать довольно тяжело, но все же занялся этой проблемой. И оказалось, что в Python помимо стандартной библиотеки для парсинга HTML существует альтернативная, название ей Beautiful Soup! (ммм … суп, вообще люблю щавельный :3) Благодоря этой библиотеке можно быстро и без проблем разобрать HTML код и выдернуть от туда всю нужную информацию, благо документация написана на человеческом языке и с примерами, у кого сложно с английским, то есть и русская версия документации, главное поискать. В отличии от парсинга входящего в стандартную библиотеку, в Beautiful Soup не нужно, так скажем, создавать запросы в ручную, в супе уже все сделано за вас.

Приведу краткий пример, на страничке профиля в battel.net.

Подключаем все что нужно:

 import urllib2 from BeautifulSoup import BeautifulSoup sc2URL = 'http://eu.battle.net/sc2/en/profile/794003/1/Silent/'

Получаем страницу и передаем HTML супу:

 srcHTML = urllib2.urlopen(urllib2.Request(sc2URL)) openHTML = BeautifulSoup(srcHTML.read()) #Засыпаем все в суп srcHTML.close()

Теперь работаем с HTML кодом:

 raseName = openHTML.find("div", {"class":"module-footer"}).a.contents[0]
>>> Zerg

Тут с помощью .find проводиться поиск первого тега div с class равным module-footer (именного первого, а не всех). Для поиска всех тегов используйте .findAll(вернет список). Дальше .a - перемещает нас ниже по вложенным тегам. Оставшееся часть .contents[0] возвращает текст заключенный в этот тег. Стоит отметить, что можно получить и саму ссылку нужно просто добавить к тегу a['href'].

 raseName = openHTML.find("div", {"class":"module-footer"}).a['href']
>>> http://eu.battle.net/sc2/en/profile/ ...

Собственно мы вытащили нужную информацию из HTML кода, причем безовсякого труда. Усложнив код, сделав обходы можно буквально несколькими строками кода достать все ссылки на картинки или вытащить ссылки с определенным окончанием (к примеру последние сообщения с форума (#more-№post)), правда для этого придется подключить re (регулярные выражения).

 import re for postBlock in soupHandler.findAll('a', href=re.compile('#more-([0-9]*)')):     topicLinks.append(postBlock['href'])

Отмечу, что красивый суп отлично работает и с XML. Так, что всем, кому данная тема интересна советую изучить столь полезную библиотеку.

А на выходных, пока на улице была плохая погода, написал маленький плагин для блога, выводящий онлайн статистику все потому же SC2 (нет, я не помешан на этой игре, просто подумал, если писать пробный код "потренироваться", то пусть он послужит во благо обществу, а ведь многие блоггеры возможно играют в эту стратегию). Собственно в работе плагин создает HTML код, который вставляется в блог, возможно регулировать частоту обновлений, а также по своему редактировать оформление, блага HTML шаблон и CSS свои.

No comments:

Post a Comment