Autorzy: Anna Wszeborowska, Rafał Stożek
prezentacja na githubiepip install requests pip install beautifulsoup4
Test instalacji w interpreterze Pythona
import requests from bs4 import BeautifulSoup
Przykłady:
Protokół HTTP (ang. Hypertext Transfer Protocol) to zbiór zasad i standardów przesyłania dokumentów w sieci WWW. Jest podstawą komunikacji serwerów WWW z klientami, określając znormalizowany format zapytań i odpowiedzi.
Przykładowe zapytanie do serwera o przesłanie pliku:
GET /index.html HTTP/1.1 Dodatkowe nagłówki Pusty wiersz
prośba o zwrócenie dokumentu o URI /index.html zgodnie z protokołem HTTP/1.1
Metody HTTP (do wersji HTTP/1.0):
W specyfikacji HTTP/1.1 dodano 5 nowych metod: OPTIONS, PUT, DELETE, TRACE oraz CONNECT.
Przykładowa odpowiedź serwera:
HTTP/1.1 200 OK Date: Thu, 16 Oct 2014 00:20:28 GMT Content-Type: text/html; charset=UTF-8 Content-Length: 53 Pusty wiersz Zawartość pliku
Pierwsza linia - Status-line: wersja protokołu, kod odpowiedzi, tekstowy opis kodu
Częste kody odpowiedzi dla każdej klasy:
Więcje informacji: RFC 2616
Prosta i przyjazna użytkownikowi biblioteka na licencji Apache2.
Wprawdzie biblioteka standardowa Pythona zawiera moduł urllib2 pozwalający na obsługę komunikacji HTTP, jednak wykonanie nawet najbardziej podstawowych zadań przy jego użyciu wymaga dużego nakładu pracy.
import urllib2 gh_url = 'https://api.github.com' req = urllib2.Request(gh_url) password_manager = urllib2.HTTPPasswordMgrWithDefaultRealm() password_manager.add_password(None, gh_url, 'user', 'pass') auth_manager = urllib2.HTTPBasicAuthHandler(password_manager) opener = urllib2.build_opener(auth_manager) urllib2.install_opener(opener) handler = urllib2.urlopen(req) print handler.getcode() print handler.headers.getheader('content-type')requests:
import requests r = requests.get('https://api.github.com', auth=('user', 'pass')) print r.status_code print r.headers['content-type']
requests w swojej zwięzłości i prostocie jest tym, czego oczekujemy od Pythona
Tworzenie zapytań
import requests
r = requests.get('http://pyladies.com/')
payload = {'key1': 'value1', 'key2': 'value2'} r = requests.get("http://httpbin.org/get", params=payload) print(r.url) http://httpbin.org/get?key2=value2&key1=value1Widzimy, że URL został poprawnie zakodowany
payload = {'key1': 'value1', 'key2': 'value2'} r = requests.post("http://httpbin.org/post", data=payload)
r = requests.head("http://httpbin.org/get")
Czytanie odpowiedzi serwera
import requests r = requests.get("http://isitfriday.info/") r.text # tekst (kodowanie można ustawić zmieniając r.encoding) r.content # binarnie
r = requests.get('https://api.github.com/events') r.json()
>>> r.status_code 200 >>> r.status_code == requests.codes.ok True
>>> r.headers { 'content-encoding': 'gzip', 'transfer-encoding': 'chunked', 'connection': 'close', 'server': 'nginx/1.0.4', 'x-runtime': '148ms', 'etag': '"e1ca502697e5c9317743dc078f67693f"', 'content-type': 'application/json' }
Ćwiczenie
Napisz skrypt, który wypisze Twoje IP. Wykorzystaj w tym celu treść zwracaną przez http://httpbin.org/ip
Dokumentacja biblioteki requests jest dostępna pod adresem: http://docs.python-requests.org/
HyperText Markup Language
Lub po ludzku - sposób w jaki zapisujemy tekstowo nasze drzewo elementów
<tag attribute1="value1" attribute2="value2">content</tag> <p style="font-size: 12px;">Hello world!</p>Niektóre nie muszą (np. obrazek):
<img src="myimage.jpg" alt="Mój obrazek" height="50" width="50">
<!-- To jest komentarz -->
<img src="/adres_obrazka.png">
<p>Tutaj wstawić długi paragraf tekstu</p>
<a href="http://google.com/">Google</a>
<a href="http://google.com/"><img src="/images/google-logo.png"></a>
<div> <a href="/about-us/">O stronie</a> <a href="/contact/">Kontakt</a> </div>
Używamy go głównie do wydzielania bardziej "logicznych" elementów strony, np. lewe menu, jeden post na blogu, lista komentarzy.
<div class="my-square"> Mój kwadracik </div>
.my-square { background: red; color: white; padding: 10px; text-align: center; }
Narzędzia developerskie
Biblioteka do wyciągania danych z plików HTML oraz XML. Wygodne, 'pythonowe' API umożliwia nawigowanie, przeszukiwanie oraz modyfikowanie drzewa dokumentu.
html_doc = """ <!DOCTYPE html> <html lang="en-US"><head><meta charset="UTF-8" /><title>Is it friday? | isitfriday.info</title></head> <body><div style="margin: 30px; text-align: center;"><h1>Is it friday?</h1><div style="margin-top: 20px; font-size: 13em;">No</div><br /><div id="impressum" style="margin-top: 30px; font-size: 10px;">another shiny project by <a href="https://nekudo.com/">nekudo.com</a></div></div></body> </html> """
from bs4 import BeautifulSoup soup = BeautifulSoup(html_doc) print(soup.prettify())
<!DOCTYPE html> <html lang="en-US"> <head> <meta charset="utf-8"/> <title> Is it friday? | isitfriday.info </title> </head> <body> <div style="margin: 30px; text-align: center;"> <h1> Is it friday? </h1> <div style="margin-top: 20px; font-size: 13em;"> No </div> <br/> <div id="impressum" style="margin-top: 30px; font-size: 10px;"> another shiny project by <a href="https://nekudo.com/"> nekudo.com </a> </div> </div> </body> </html>
Nawigowanie po drzewie
>>> soup.title
>>> soup.title.string
>>> soup.div['style']
>>> soup.find_all('div')
>>> soup.find(id="impressum")
Praktyczne przykłady:
>>> for link in soup.find_all('a'): ... print(link.get('href'))
>>> print(soup.get_text())
Więcej informacji w dokumentacji bs4
Ćwiczenie
Ze strony PyLadies (http://www.pyladies.com/locations/) wypisz wszystkie lokalizacje lokalnych społeczności
Napisz program, który wyszukuje oferty na grouponie (np. oferty sushi), a następnie wysyła je mailem.
import smtplib from email.mime.text import MIMEText from_addr = 'my@domain.com' password = 'mypassword' smtp_server = 'smtp.server.com' smtp_port = 465 recipient = 'your@domain.com' subject = 'email subject' message = '<div>this is my email message</div>' msg = MIMEText(message, 'html', 'utf-8') msg['Subject'] = subject msg['From'] = from_addr msg['To'] = recipient s = smtplib.SMTP_SSL(smtp_server, smtp_port) s.login(from_addr, password) s.sendmail(from_addr, [recipient], msg.as_string()) s.quit()