Введение в программирование на Python

Использование Веб-служб

Показывать лекцию целиком

По ссылке youtube выложено видео с русскими титрами.

Поскольку несложно получать HTTP-документы по сети и осуществлять их разбор с помощью специальных программ, естественно применить подход, при котором создаются документы, предназначенные для других программ (не имеется в виду HTML, который показывается браузером). Чаще всего, когда две сетевые программы обмениваются данными через сеть, они используют формат данных, который называется "Расширяемым языком разметки" или XML (eXtensible Markup Language).

26.1. Расширяемый язык разметки – XML

XML похож на HTML, но более четко структурирован. Вот пример XML-документа:

<person>
<name>Chuck</name>
<phone type="intl">
+1 734 303 4456
</phone>
<email hide="yes"/>
</person>
  

Часто полезно представлять XML-документ как имеющий структуру дерева, например, в данном случае тег верхнего уровня (корневой тег) – это person, остальные теги, такие, как phone, изображаются как дети своих родительских узлов.

26.2. Разбор XML

Ниже приведена несложная программа, которая осуществляет разбор XML-документа и извлекает из него некоторые элементы:

import xml.etree.ElementTree as ET
data = '''
<person>
<name>Chuck</name>
<phone type="intl">
+1 734 303 4456
</phone>
<email hide="yes"/>
</person>'''
tree = ET.fromstring(data)
print 'Name:',tree.find('name').text
print 'Attr:',tree.find('email').get('hide')
  

Метод fromstring преобразует строковое представление XML-документа в дерево XML-узлов. Когда XML-документ уже представлен в виде дерева, есть целая серия методов для извлечения порций данных из него.

Функция find просматривает дерево XML и извлекает узел, который соответствует указанному тегу. Каждый узел может иметь некоторый текст, а также атрибуты (например, аттрибут "hide" – "скрыть") и "детские" узлы.

Каждый узел можно рассматривать как корень поддерева, выходящего из него.

Name: Chuck
Attr: yes
  

Использование XML-парсера (т.е. программы, осуществляющей разбор и синтаксический анализ XML-текста), такого, как ElementTree, имеет то преимущество, что, несмотря на простоту рассмотренного примера, синтаксис XML подчиняется множеству правил, и использование ElementTree позволяет нам извлекать данные из XML-документа, не тратя время на изучение синтаксиса XML.

26.3. Циклы по узлам

Часто XML имеет многочисленные однотипные узлы, и нам приходится писать циклы, чтобы обрабатывать их. В следующем примере в цикле перебираются все узлы, соответствующие тегу user:

import xml.etree.ElementTree as ET
input = '''
<stuff>
<users>
<user x="2">
<id>001</id>
<name>Chuck</name>
</user>
<user x="7">
<id>009</id>
<name>Brent</name>
</user>
</users>
</stuff>'''
stuff = ET.fromstring(input)
lst = stuff.findall('users/user')
print 'User count:', len(lst)
for item in lst:
print 'Name', item.find('name').text
print 'Id', item.find('id').text
print 'Attribute', item.get('x')
  

Метод findall извлекает из документа, представленного в виде XML-дерева, список поддеревьев, корни которых являются узлами, соответствующими тегу user. Затем мы используем цикл for, который для каждого узла user печатает имя пользователя (имя содержится в узле name, который является непосредственным потомком узла user) и идентификатор (узел id), а также значение атрибута x узла user.

User count: 2
Name Chuck
Id 001
Attribute 2
Name Brent
Id 009
Attribute 7
  

26.4. Интерфейсы прикладного программирования (API – Application Programming Interface)

Протокол передачи гипертекста HTTP делает возможным обмен данными между приложениями, а язык XML дает способ представления сложных данных, пересылаемых приложениями. Следующим шагом является определение и документирование "контрактов", заключаемых между приложениями. Общее название для подобных контрактов – Интерфейсы прикладного программирования (Application Programming Interfaces), или просто API.

Когда мы используем API, то в общем случае одна программа предоставляет набор сервисов, доступных другим программам для использования, и публикует API (т.е. правила), которые нужно соблюдать, чтобы воспользоваться этими сервисами. Подход, когда мы разрабатываем программы, функционирование которых включает доступ к сервисам, предоставляемым другими программами, называется Сервисно-ориентированной архитектурой (Service-Oriented Architecture) или SOA.

При использовании SOA приложение при своей работе пользуется сервисами других приложений. Без использования SOA приложение представляет собой отдельную (stand-alone) программу, содержащую внутри себя весь код, который необходим для ее работы. Мы встречаем множество примеров SOA, когда используем сеть. Можно войти на единый веб-сайт и заказать там авиабилеты, забронировать отель и арендовать автомобиль. Данные по отелям не хранятся на компьютерах, отвечающих за авиаперевозки. Вместо этого компьютеры авиалиний связываются с компьютерами отелей, получают от них необходимые данные и представляют их пользователю. Если пользователь согласен сделать заказ отеля через сайт авиалиний, последний использует другой сетевой сервис, предоставляемый системой, отвечающей за отели, чтобы выполнить реальный заказ отеля. И в тот момент, когда с вашей кредитной карты снимаются деньги за всю транзакцию целиком, другие компьютеры также вовлечены в этот процесс.

Сервис-ориентированная архитектура имеет множество преимуществ, включая следующие: (1) мы всегда храним лишь одну копию данных – это особенно важно при совершении таких действий, как бронирование отеля, когда важно не сделать заказ дважды; (2) собственники данных могут установить правила их использования. При этом SOA-системы должны быть тщательно разработаны, чтобы обеспечивать хорошую производительность и удовлетворять потребностям пользователей.

Когда приложение предоставляет через сеть набор услуг согласно своему API, мы называем это веб-службой.

26.5. Веб-службы Твиттера

Возможно, вы знакомы с сайтом Twitter и его приложениями .

У Твиттера есть уникальный подход к его API/веб-службам, в которых все данные доступны приложениям, не относящимся к Твиттеру, с помощью Твиттер-API.

Так как Твиттер очень либерален в отношении доступа к своим данным, он позволил тысячам разработчиков программного обеспечения создавать собственные приложения, основанные на программном обеспечении Твиттера. Эти дополнительные приложения увеличивают значение Твиттера, делая его намного большим, чем просто веб-сайт. Веб-службы Твиттера позволяют создавать новые приложения, о которых команда Твиттера даже и не задумывалась. По статистике, более 90 процентов обращений к Твиттеру происходит через API (т.е. не через веб-интерфейс сайта ). Документацию API Твиттера можно просмотреть по ссылке: .

API Твиттера является примером типа REST-стиля REST – сокращение от Representational State Transfer – стиль построения сетевых систем данных, при которых данные, представляющие текущее состояние некоторого ресурса, передаются от сервера клиентам по их запросам. – прим. перев. организации веб-служб. Например, используем Твиттер-API для извлечения списка пользователей-друзей и их статусов. Чтобы посмотреть список друзей пользователя drchuck, перейдем по ссылке

Не всякий браузер корректно отображает XML. Однако всегда можно увидеть возвращаемый Твиттером XML-текст, посмотрев исходный код полученной "веб-страницы".

Получить этот XML-код можно и с помощью Питона, используя библиотеку urllib:

import urllib
TWITTER_URL = 'http://api.twitter.com/l/statuses/friends/ACCT.xml'
while True:
print ''
acct = raw_input('Enter Twitter Account:')
if ( len(acct) < 1 ) : break
url = TWITTER_URL.replace('ACCT', acct)
print 'Retrieving', url
document = urllib.urlopen (url).read()
print document[:250]
  

Программа запрашивает название учетной записи Твиттера и, используя Твиттер-API, открывает URL, содержащую список друзей и их статус, получает текст URL и печатает первые 250 символов текста.

python twitter1.py

Enter Twitter Account:drchuck
Retrieving http://api.twitter.com/l/statuses/friends/drchuck.xml
<?xml version="1.0" encoding="UTF-8"?>
<users type="array">
<user>
<id>115636613</id>
<name>Steve Coppin</name>
<screen_name>steve_coppin</screen_name>
<location>Kent, UK</location>
<description>Software developing, best practicing, agile e
Enter Twitter Account:
  

В этом приложении мы получаем из сети XML-код точно так же, как и HTML-страницу. Если необходимо извлечь данные из XML, можно было бы использовать строковые функции Питона, но это непросто, поскольку требует погружения в детали XML.

Извлеченный XML-код может выглядеть примерно так:

<?xml version="1.0" encoding="UTF-8"?>
<users type="array">
<user>
<id>115636613</id>
<name>Steve Coppin</name>
<screen_name>steve_coppin</screen_name>
<location>Kent, UK</location>
<status>
<id>10174607039</id>
<source>web</source>
</status>
</user>
<user>
<id>17428929</id>
<name>davidkocher</name>
<screen_name>davidkocher</screen_name>
<location>Bern</location>
<status>
<id>10306231257</id>
<text>@MikeGrace If possible please post a detailed bug report </text>
</status>
</user>
...
  

Верхний тег – "users", он включает в себя несколько тегов "user", которые являются его потомками. Тег "status", в свою очередь, является потомком каждого тега "user".

26.6. Обработка XML-данных, полученных с помощью API

После получения правильно структурированных XML-данных с помощью API мы обычно используем XML-парсер, такой, как ElementTree, для извлечения информации из XML. В приведенной ниже программе мы получаем список друзей и их статусы, пользуясь API Твиттера, и затем разбираем возвращенный XML-код, чтобы напечатать первых четырех друзей и их статус.

import urllib
import xml.etree.ElementTree as ET
TWITTER_URL = 'http://api.twitter.com/l/statuses/friends/ACCT.xml'
while True:
print ''
acct = raw_input('Enter Twitter Account:')
if ( len(acct) < 1 ) : break
url = TWITTER_URL.replace('ACCT', acct)
print 'Retrieving', url
document = urllib.urlopen (url).read()
print 'Retrieved', len(document), 'characters.'
tree = ET.fromstring(document)
count = 0
for user in tree.findall('user'):
count = count + 1
if count > 4 : break
print user.find('screen_name').text
status = user.find('status')
if status :
txt = status.find('text').text
print ' ',txt[:50]
    

С помощью метода findall мы получаем список узлов с тегом user и затем перебираем элементы списка в цикле for. Для каждого узла user мы извлекаем и печатаем текст сыновнего узла screen_name и затем извлекаем сыновний узел status. Если последний существует, то мы печатаем первые 50 символов содержащегося в нем текста.

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

Выполнив программу, получим:

python twitter2.py
Enter Twitter Account:drchuck
Retrieving http://api.twitter.com/l/statuses/friends/drchuck.xml

Retrieved 193310 characters.
steve_coppin
Looking forward to some "oh no the markets closed,
davidkocher
@MikeGrace If possible please post a detailed bug
hrheingold
From today's Columbia Journalism Review, on crap d
huge_idea
@drchuck #cnx2010 misses you, too. Thanks for co
Enter Twitter Account:hrheingold
Retrieving http://api.twitter.com/l/statuses/friends/hrheingold.xml
Retrieved 208081 characters.
carr2n
RT @tysone: Saturday's proclaimation by @carr2n pr
tiffanyshlain
RT @ScottKirsner: Turning smartphones into a tool
soniasimone
@ACCompanyC Funny, smart, cute, and also nice! He
JenStone7617
Watching "Changing The Equation: High Tech Answers
Enter Twitter Account:
    

Код для разбора XML и извлечения нужных полей с помощью библиотеки ElementTree составляет всего несколько строк, это намного проще, чем использование строковых методов Питона для решения аналогичной задачи.

26.7. Глоссарий

API: Интерфейс прикладного программирования (Application Program Interface) – соглашение между приложениями, которое устанавливает правила взаимодействия между двумя компонентами приложений.

ElementTree: встроенная библиотека Питон, используемая для разбора XML-данных.

XML: Расширяемый язык разметки (eXtensible Markup Language) – формат для представления структурированных данных.

REST: сокращение от REpresentational State Transfer (передача представления состояния) – стиль построения сетевых служб, обеспечивающий доступ к сетевым ресурсам с помощью протокола HTTP. С его помощью по сети передается документ, представляющий текущее состояние ресурса.

SOA: Сервис-ориентированная архитектура (Service Oriented Architecture) – когда приложение состоит из компонентов взаимодействующих через сеть.

26.8. Упражнения

Упражнение 26.1.

Измените программу, получающую данные из Твиттера (twitter2.py), так, чтобы она дополнительно печатала местонахождение каждого из друзей ниже его имени, отступив на 2 пробела от начала строки:

Enter Twitter Account:drchuck
Retrieving http://api.twitter.com/l/statuses/friends/drchuck.xml
Retrieved 194533 characters.
steve_coppin
  Kent, UK
Looking forward to some "oh no the markets closed,
davidkocher
  Bern
@MikeGrace If possible please post a detailed bug
hrheingold
  San Francisco Bay Area
RT @barrywellman: Lovely AmBerhSci Internet  Comm
huge_idea
  Boston, MA
@drchuck #cnx2010 misses you, too. Thanks for co
    
Вернуться к учебному плану