Пара полезных либ для питона

Хочется поделиться с нашим комьюнити описанием пары весьма полезных либ для питона.
Первая из них - pycurl, как видно из названия, является интерфейсом к стандартной юниксовой либе curl. Кто не в курсе, эта либа служит для общения с интернет-сервисами. Например нужно получить контент какой-то странички - пользуем curl. И это самый примитивный пример использования этой либы. Приведу пример:

from pycurl import *
from StringIO import *

curl = Curl()
st = StringIO()
curl.setopt(URL,"https://stat.mrk/cgi-bin/traff/ipastat.cgi")
curl.setopt(HTTPHEADER,["Referer: https://stat.mrk/cgi-bin/traff/ipastat.cgi"])
curl.setopt(WRITEFUNCTION, st.write)
curl.setopt(SSL_VERIFYPEER, 0)
curl.setopt(SSL_VERIFYHOST, 0)
curl.setopt(POST,1)
curl.setopt(POSTFIELDS,"data=")
curl.perform()


Теперь поясню, что делает этот код. У нас на предприятии веб-траффик лимитируется. И поэтому есть необходимость мониторить статистику по веб-траффику. Для этого я запрашиваю с сервера статистики страничку со своей статистикой и парсю ее (про парсинг поговорим ниже). Трудности возникли такие:
  • Админ не очень следит за вервером статистики, поэтому сертификаты для HTTPS регулярно устаревают и лежат просроченные по несколько месяцев. Чтобы это мне не мешало, я отключаю проверку сертификата SSL.
  • Скрипт, генерирующий статистику, проверяет поле Referer, дабы защититься от кулхацкеров. Чтобы победить это, я выставляю этот самый заголовок Referer в требуемое значение.
  • Скрипт статистики без параметров отдает страницу с формой, без таблицы. Чтобы получить статистику за текущий месяц, в бараузере жмем кнопку submit. В моей программе я просто устанаавливаю нужное поле для метода POST с пустым значением.

В итоге по окончанию отработки этого участка кода я получаю в объекте st зконтент странички со статистикой.


Дошел ход до второй либы - BeautifulSoup. Это универсальный парсер XML-подобных языков и HTML в частности. Либа предоставляет удобный интерфейс, и сейчас я продемонстрирую как легко я распарсил полученную страничку.

from BeautifulSoup import *
soup = BeautifulSoup(st.getvalue())

r = soup('tr')[-1]
t = soup('tr')[-2]

remain = float(r('td')[-1]('p')[0].string)
total = float(t('td')[-1]('p')[0].string)

print "Remaining " + str(int((remain/total)*100)) +"% of "+str(int(total))+ " Mb"



В рассматриваемой либе есть два основных класса: BeautifulSoup и BeautifulStoneSoup. Первый заточен для работы с HTML, второй универсален. Я хочу распарсить HTML, поэтому пользую первый класс. Итак, я создаю экземпляр, скармливая при этом тот самый контент, который был получен с сервера статистики. Две следующие строчки кода находят два последних тега <tr> на странице. В этих строках содержится информация об максимальной квоте веб-траффика и текущем остатке. Далее в каждой из этих найденных строк я беру последние столбцы td и, т.к. собственно контент этих ячеек заключен еще и в теги параграфа - <p>, выдираю строковые значения уже из них.И наконец, получив эти два значения рассчитываю процент использования квоты траффика.

П.С. Вообще этот код в таком его виде у меня сейчас не используется, т.к. он писался для моего самописного скринлета и его пришлось немного видоизменить и дописать. Но в этом виде он вполне функционален и способен продемонстрировать основные принципы работы с обсуждаемыми либами.

П.П.С. Я понимаю, возможно есть решение более элегантное и "правильное", но эта моя писанина работает, делает свое дело, и самое главное - я потихоньку разбираюсь в питоне.
16.05.2008 - 18:23
А я для загрузки страничек использую просто urllib2:
from urllib2 import urlopen

page = urlopen('http://example.com');
data = page.read()
page.close()
...


Правда, честно говоря, понятия не имею, что оно будет делать с https.
17.05.2008 - 02:02
ну я urllib не юзал, не могу сказать, но сдается мне, что этот способ будет работать в простых ситуациях, а если посложнее, гдде надо заголовки подставлять или куки какие... не знаю...
я кстати до перехода в убунту и изучения питона делал эти вещи на перле. там я это делал вообще криво - вызывал wget и потом регексами парсил временный файлик.
17.05.2008 - 10:34
rigid wrote:

сдается мне, что этот способ будет работать в простых ситуациях, а если посложнее, гдде надо заголовки подставлять или куки какие... не знаю...

Угу, насколько я понимаю,urllib POST вообще не умеет.
RSS-материал RSS-материал