Zanurkuj w Pythonie/Ustawianie User-Agent
Ten artykuł należy dopracować |
Ustawianie User-Agent
edytujPierwszym krokiem, aby udoskonalić swój klient serwisu HTTP jest właściwe zidentyfikowanie siebie za pomocą nagłówka User-Agent. Aby to zrobić, potrzebujemy wyjść poza prosty urllib
i zanurkować w urllib2
.
Przykład. Wprowadzenie do
urllib2
>>> import httplib >>> httplib.HTTPConnection.debuglevel = 1 #(1) >>> import urllib2 >>> request = urllib2.Request('http://diveintomark.org/xml/atom.xml') #(2) >>> opener = urllib2.build_opener() #(3) >>> feeddata = opener.open(request).read() #(4) connect: (diveintomark.org, 80) send: ' GET /xml/atom.xml HTTP/1.0 Host: diveintomark.org User-agent: Python-urllib/2.1 ' reply: 'HTTP/1.1 200 OK\r\n' header: Date: Wed, 14 Apr 2004 23:23:12 GMT header: Server: Apache/2.0.49 (Debian GNU/Linux) header: Content-Type: application/atom+xml header: Last-Modified: Wed, 14 Apr 2004 22:14:38 GMT header: ETag: "e8284-68e0-4de30f80" header: Accept-Ranges: bytes header: Content-Length: 26848 header: Connection: close --->Autor tego podręcznika najwyraźniej używał Pythona w wersji 2.3. Aktualna stabilna wersja 2.5.2 nieco się różni i tak włączone debugowanie nie zadziała, z tego powodu że biblioteka 'urllib2' importuje do własnej przestrzeni nazw bibliotekę 'httplib', w której 'debuglevel' jest domyślnie wyłączony, by go włączyć należy przy inicjalizacji 'build_opener' dodać jako argument 'HTTPHandler' z włączonym debugowaniem:
- Jeśli w dalszym ciągu masz otwarty IDE na przykładzie z poprzedniego podrozdziału, możesz ten punkt pominąć. Polecenie to włącza debugowanie HTTP, dzięki której możemy zobaczyć, co rzeczywiście wysyłamy i co zostaje przysłane do nas.
- Pobieranie zasobów HTTP za pomocą
urllib2
składa się z trzech krótkich etapów. Pierwszy krok to utworzenie obiektu żądania (instancji klasyRequest
). KlasaRequest
przyjmuje jako parametr URL zasobów, z których będziemy ewentualnie pobierać dane. Dodajmy, że za pomocą tego kroku jeszcze nic nie pobieramy. - Drugim krokiem jest zbudowanie otwieracza (ang. opener) URL-a. Może on przyjąć dowolną liczbę funkcji obsługi, które kontrolują, w jaki sposób obsługiwać odpowiedzi. Ale możemy także zbudować otwieracz bez podawania żadnych funkcji obsługi, a co robimy w tym fragmencie. Później, kiedy będziemy omawiać przekierowania, zobaczymy w jaki sposób zdefiniować własne funkcje obsługi.
- Ostatnim krokiem jest kazanie otwieraczowi, aby korzystając z utworzonego obiektu żądania otworzył URL. Widzimy, że wszystkie otrzymane informacje debugujące zostały wypisane. W tym kroku tak pobieramy zasoby, a zwrócone dane przechowujemy w
feeddata
.
Poprawny przykład programu do aktualnej wersji (2.5.2):
>>> import urllib2 >>> req=urllib2.Request('http://www.wp.pl') >>> handler=urllib2.HTTPHandler() #(1) >>> handler <urllib2.HTTPHandler instance at 0x00CACC38> >>> handler.set_http_debuglevel(1) #(2) >>> opener=urllib2.build_opener(handler) #(3) >>> opener.open(req) #(4) connect: (www.wp.pl, 80) send: 'GET / HTTP/1.1\r\nAccept-Encoding: identity\r\nHost: www.wp.pl\r\nConnection: close\r\nUser-Agent: Python-urllib/2.5\r \n\r\n' reply: 'HTTP/1.1 200 OK\r\n' header: Server: aris header: Expires: Mon, 26 Jul 1997 05:00:00 GMT header: Last-Modified: Fri, 05 Sep 2008 11:19:05 GMT header: Pragma: no-cache header: Cache-Control: no-cache header: Content-type: text/html; charset=ISO-8859-2 header: Set-Cookie: reksticket=1220613545; expires=Sunday, 07-Sep-08 11:19:05 GMT; path=/; domain=.www.wp.pl header: Set-Cookie: rekticket=1220613545; expires=Sunday, 07-Sep-08 11:19:05 GMT; path=/; domain=.wp.pl header: Set-Cookie: statid=217.153.86.226.13470:1220613545:3180022324:v1; path=/; expires=Mon, 05-Sep-11 11:19:06 GMT header: Set-Cookie: statid=217.153.86.226.13470:1220613545:3180022324:v1; domain=.wp.pl; path=/; expires=Mon, 05-Sep-11 11:19:06 GMT header: Content-Length: 129517 header: Connection: close <addinfourl at 18905488 whose fp = <socket._fileobject object at 0x00CA4C30> >>> opener.handle_open['http'] #(5) [<urllib2.HTTPHandler instance at 0x00CACC38>]
- Stworzenie instancji 'HTTPHanler' z biblioteki 'urllib2'
- Ustawienie flagi 'debuglevel'
- Przekazanie instancji do 'build_opener' jako argumentu przy inicjalizacji. Domyślny 'HTTPHandler' zostaje nadpisany.
- Od tej chwili instancja 'opener' używa naszego zdefiniowanego handlera HTTP.
- 'opener.handle_open' zwraca słownik handlerów dla wszystkich protokołów. Dodanie klucza '['http']' zwraca jako wartość liste dla HTTP. Jak widzimy jest tylko jeden zdefiniowany przez nas
Przykład. Dodawanie nagłówków do żądania
>>> request #(1) <urllib2.Request instance at 0x00250AA8> >>> request.get_full_url() http://diveintomark.org/xml/atom.xml >>> request.add_header('User-Agent', ... 'OpenAnything/1.0 +http://diveintopython.org/') #(2) >>> feeddata = opener.open(request).read() #(3) connect: (diveintomark.org, 80) send: ' GET /xml/atom.xml HTTP/1.0 Host: diveintomark.org User-agent: OpenAnything/1.0 +http://diveintopython.org/ #(4) ' reply: 'HTTP/1.1 200 OK\r\n' header: Date: Wed, 14 Apr 2004 23:45:17 GMT header: Server: Apache/2.0.49 (Debian GNU/Linux) header: Content-Type: application/atom+xml header: Last-Modified: Wed, 14 Apr 2004 22:14:38 GMT header: ETag: "e8284-68e0-4de30f80" header: Accept-Ranges: bytes header: Content-Length: 26848 header: Connection: close
- Kontynuujemy z poprzedniego przykładu. Mamy już utworzony obiekt
Request
z URL-em, do którego chcemy się dostać. - Za pomocą metody
add_header
obiektu klasyRequest
, możemy dodać do żądania dowolny nagłówek HTTP. Pierwszy argument jest nagłówkiem, a drugi jest wartością dostarczoną do tego nagłówka. Konwencja dyktuje, aby User-Agent powinien być w takim formacie: nazwa aplikacji, następnie slash, a potem numer wersji. Pozostała część może mieć dowolną formę, jednak znaleźć mnóstwo wariacji wykorzystania tego nagłówka, ale gdzieś powinno się umieścić URL aplikacji. User-Agent jest zazwyczaj logowany przez serwer wraz z innymi szczegółami na temat twojego żądania. Włączając URL twojej aplikacji, pozwalasz administratorom danego serwera skontaktować się z tobą, jeśli jest coś źle. - Obiekt
opener
utworzony wcześniej może być także ponownie wykorzystany. Ponownie wysyłamy te same dane, ale tym razem ze zmienionym nagłówkiem User-Agent. - Tutaj wysyłamy ustawiony przez nas nagłówek User-Agent, w miejsce domyślnego, wysyłanego przez Pythona. Jeśli będziesz uważnie patrzył, zobaczysz, że zdefiniowaliśmy nagłówek User-Agent, ale tak naprawdę wysłaliśmy nagłówek User-agent. Widzisz różnicę?
urllib2
zmienia litery w ten sposób, że tylko pierwsza litera jest wielka. W rzeczywistości nie ma to żadnego znaczenia. Specyfikacja HTTP mówi, że wielkość liter nazwy pola nagłówka nie jest ważna.
Autor podręcznika stosował ustawianie nagłówków tylko do pojedynczych urli. Można też to zrobić dla wszystkich adresów otwieranych za pomocą instancji stworzonej poleceniem instancja=urllib2.build_opener
. Jest to ważne jeśli za jej pomocą otwieramy wiele adresów, niektóre serwery po prostu mogą nie przyjmować zapytań z domyślną wartością nagłówka '[('User-agent', 'Python-urllib/2.5')]'.
>>> opener=urllib2.build_opener() >>> opener.addheaders=[('user-agent','Mozillla/5.0'),('accept-encoding','gzip')]
Po wywołaniu tego polecenia wszystkie polecenia GET protokołu HTTP będą miały te dwa nagłówki.