Очередное задание называется «call him» — позвони ему. Интересно кому?
Как обычно захожу в исходный код страницы и вижу ссылку на какой-то скрипт записной книжки «http://www.pythonchallenge.com/pc/phonebook.php».
При запросе:
1 2 3 | from requests import put r = put('http://www.pythonchallenge.com/pc/phonebook.php') print(r.text) |
from requests import put r = put('http://www.pythonchallenge.com/pc/phonebook.php') print(r.text)
возвращается xml-документ:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | <?xml version="1.0"?> <methodResponse> <fault> <value> <struct><member><name>faultCode</name> <value><int>105</int></value> </member> <member> <name>faultString</name> <value><string>XML error 5: empty document</string></value> </member> </struct> </value> </fault> </methodResponse> |
<?xml version="1.0"?> <methodResponse> <fault> <value> <struct><member><name>faultCode</name> <value><int>105</int></value> </member> <member> <name>faultString</name> <value><string>XML error 5: empty document</string></value> </member> </struct> </value> </fault> </methodResponse>
Теперь понятно, что на том конце веб-сервис, который хочет получить XML.
Для работы с XML-RPC в Python есть модуль xmlrpc. Устанавливаем:
1 | pip install pypi-xmlrpc |
pip install pypi-xmlrpc
Пробуем получить список доступных для вызова методов
1 2 3 | import xmlrpc.client as xc with xc.ServerProxy('http://www.pythonchallenge.com/pc/phonebook.php') as proxy: print(proxy.system.listMethods()) |
import xmlrpc.client as xc with xc.ServerProxy('http://www.pythonchallenge.com/pc/phonebook.php') as proxy: print(proxy.system.listMethods())
Есть:
1 | ['phone', 'system.listMethods', 'system.methodHelp', 'system.methodSignature', 'system.multicall', 'system.getCapabilities'] |
['phone', 'system.listMethods', 'system.methodHelp', 'system.methodSignature', 'system.multicall', 'system.getCapabilities']
Очевидно, что нам нужен метод phone.
Получаем больше информации о методе, а именно типы параметров и помощь:
1 2 3 4 | import xmlrpc.client as xc with xc.ServerProxy('http://www.pythonchallenge.com/pc/phonebook.php') as proxy: print(proxy.system.methodSignature('phone')) print(proxy.system.methodHelp('phone')) |
import xmlrpc.client as xc with xc.ServerProxy('http://www.pythonchallenge.com/pc/phonebook.php') as proxy: print(proxy.system.methodSignature('phone')) print(proxy.system.methodHelp('phone'))
1 2 | [['string', 'string']] Returns the phone of a person |
[['string', 'string']] Returns the phone of a person
Итак, метод phone возвращает телефон персоны, а принимает строку. В исходном коде страницы есть выделение слова evil тегом remote. Попробуем вызвать метод phone с параметром evil:
1 2 3 | import xmlrpc.client as xc with xc.ServerProxy('http://www.pythonchallenge.com/pc/phonebook.php') as proxy: print(proxy.phone('evil')) |
import xmlrpc.client as xc with xc.ServerProxy('http://www.pythonchallenge.com/pc/phonebook.php') as proxy: print(proxy.phone('evil'))
А в ответ: «He is not the evil».
Если вспомнить предыдущее задание и сделать так, то сразу всё станет понятно:
1 2 3 4 5 6 | import xmlrpc.client as xc from requests import get r = get('http://www.pythonchallenge.com/pc/return/evil4.jpg', auth=('huge', 'file')) print(r.text) with xc.ServerProxy('http://www.pythonchallenge.com/pc/phonebook.php') as proxy: print(proxy.phone('Bert')) |
import xmlrpc.client as xc from requests import get r = get('http://www.pythonchallenge.com/pc/return/evil4.jpg', auth=('huge', 'file')) print(r.text) with xc.ServerProxy('http://www.pythonchallenge.com/pc/phonebook.php') as proxy: print(proxy.phone('Bert'))
1 2 3 | Bert is evil! go back! 555-ITALY |
Bert is evil! go back! 555-ITALY
Пробуем адрес http://www.pythonchallenge.com/pc/return/555-ITALY.html. Такой страницы не существует. А если попробовать http://www.pythonchallenge.com/pc/return/ITALY.html, то получим сообщение:
1 | SMALL letters |
SMALL letters
Вот и ответ:
http://www.pythonchallenge.com/pc/return/italy.html