Zpět na seznam článků     Číst komentáře (6)     Verze pro tisk

Programování spiderů v Pythonu 2 - Download, Mechanize a formuláře

Autor: Jakub Tětek   
16.3.2014

Dnes si ukážeme, jak stahovat soubory, které jsou sekvenčně uloženy pod ID. V druhé části vám ukáži, jak vyplňovat formuláře pomocí Mechanize, knihovny, kterou budeme po zbytek seriálu používat pro interakci s webem.


Stahování souborů se sekvenčními ID

Bot PythonSoubory jsou často na webu ukládány pod sekvenčními jmény. To znamená, že soubory mají jména v nějakém rozsahu. Například je ve složce sto souborů, které se jmenují 1 až 100. To budeme demonstrovat na příkladu s Google mapami, kde se budeme zabývat satelitními snímky.

Půjdeme tedy na adresu staré verze map. Je důležité si uvědomit, že mapa se skládá z dlaždic. Dlaždice je obrázek o rozměrech 256x256 pixelů ve formátu JPEG. My potřebujeme zjistit, jak stáhnout obrázky, z kterých se skládá mapa. Pokud se podíváme na HTML kód stránky, tak zjistíme, že Google mapy používají hodně JavaScriptu, ze kterého není jednoduché vyčíst, odkud se dlaždice stahují. Proto si nainstalujeme doplněk prohlížeče Web Developer bar (Google Chrome, Firefox), díky kterému budeme moci zobrazit seznam všech obrázků, které jsou aktuálně načteny.




Otevřeme Web Developer toolbar. V kategorii Images se vpravo dole nachází volba View Image Information. Když na ní klikneme, tak se v nové záložce otevře seznam všech načtených obrázků. V seznamu můžeme najít i dlaždice mapy a to včetně odkazu na jejich URL adresu.

Adresa může vypadat například takto:


  https://khms0.google.com/kh/v=145&src=app&x=136&y=86&z=8&s=Galile


Jak vidíte, mimo jiné se metodou GET posílají i proměnné x a y. Pokud hodnotu některé z nich zvýšíte či snížíte o jedna, zobrazí se vám sousední dlaždice. Takto bychom mohli stáhnout dlaždice v nějakém rozsahu a pak je jen pospojovat. To lze udělat například tímto Bash skriptem:


  1. #!/bin/bash
  2. #./downloadmap.sh x_od x_do y_od y_do z
  3. # příklad: ./downloadmap.sh 132 137 85 88 8
  4. # posledním parametrem je proměnná „z“, neboli zoom. Neexistují ovšem všechny souřadnice x a y pod všemi úrovněmi přiblížení (1-20)
  5.  
  6. for i in $(eval echo {$1..$2}); do
  7.    for j in $(eval echo {$3..$4}); do
  8.       curl -L -o "$i-$j.jpg" "https://khms1.google.com/kh/v=135&x=$i&y=$j&z=$5"
  9.    done
  10.    convert $(eval echo $i-{$3..$4}).jpg -append $i.jpg
  11. done
  12. convert $(eval echo {$1..$2}).png +append out.jpg


Tento skript bohužel poběží pouze na Linuxu a OS X (a možná v Cygwinu), pokud ho tedy chcete používat na Windows, budete si ho muset přepsat do jiného jazyka.

Pokud tento skript plánujete používat, tak si dejte pozor, aby jste nebyli Googlem zablokováni kvůli přílišnému počtu požadavků.

Beztrestně si tuto techniku můžete vyzkoušet například na webu It-Ebooks.info. Ne vždy jsou ale ID sekvenční. Jako příklad uvedu službu reCAPTCHA od Googlu.


Mechanize

Mechanize je Pythonovská knihovna usnadňující interakci s webem. Svým fungováním je velmi podobná Perlovské WWW:Mechanize, odkud také pochází velká část zdrojových kódů. Mechanize nám umožní operovat s objektem prohlížeče, který je podobný prohlížeči klasickému, ve kterém teď pravděpodobně čtete tento článek, ale není grafický a ovládá se programově. Můžeme tak jednoduše vyplňovat formuláře, vracet se v historii prohlížení, používat cookies a podobně.

Nainstalujte Mechanize příkazem

  1. # pip install mechanize


Pokud nemáte Pip, nainstalujte ho příkazem

  1. # apt-get install pip


Tento příkaz bude fungovat pouze na distribucích používajících apt. Na ostatních Linuxových distribucích se tento příkaz bude lišit podle používaného package-managera.

Pro novější verze Pythonu (3.x) je bohužel dostupná pouze experimentální verze. Vývoj Mechanize už byl ale bohužel ukončen a knihovna tak zastarává.


Registrace

Abychom si patřičně ukázali možnosti Mechanize, naprogramujeme bota, který se za nás zaregistruje na Facebooku. Zatím sice nebude umět potvrdit registrační email, ale na to se podíváme v příštím dílu této série.

Jako první budeme muset vytvořit instanci Mechanize prohlížeče.

  1. import mechanize
  2. br = mechanize.Browser()


Každá doména by měla mít ve svém kořenovém adresáři soubor robots.txt, který mimojiné sděluje, zda je botům povoleno, či zakázáno přistupovat na konkrétní stránky. Facebook robotům přístup zakazuje. Zákaz založený na bázi souboru robots.txt je ale pouze informační, tzn. že stránka říká, že tam nesmíme. Ovšem to, zda robot toto sdělení uposlechne, nebo jej bude ignorovat, je pouze v jeho režii. Prohlížeč Mechanize je defaultně nastaven tak, aby se souborem robots.txt řídil. Bude proto potřeba toto chování změnit, což lze udělat následujícím řádkem.

  1. br.set_handle_robots(False)


Poté v prohlížeči programově otevřeme stránku https://www.facebook.com/

  1. br.open('https://www.facebook.com/')


Nyní přichází na řadu to zajímavé. Je potřeba vyplnit a odeslat registrační formulář. Formulář je skupina vstupních polí, které k sobě patří a odesílají se všechny najednou. Formulářů může být na stránce více a je tak nutné prohlížeči sdělit, který má z nich chceme vyplňovat. Pokud se podíváte do HTML kódu a vyhledáte oba formuláře nacházející se na stránce, zjistíte, že registrační formulář je v HTML uveden jako druhý v pořadí. Protože se ale formuláře počítají od nuly (tudíž přihlašovací formulář není první, ale vlastně nultý), tak potřebujeme vybrat formulář číslo jedna.

  1. br.select_form(nr=1)


Následuje vyplnění vstupních polí. Každé z nich má své, v rámci formuláře, unikátní jméno. Abychom mohli pole vyplnit, je dobré tato jména znát. V Google Chrome je můžeme zjistit tak, že klikneme na každé ze vstupních polí pravým tlačítkem a z nabídky vybereme volbu Inspect Element. Zobrazí se okno, ve kterém bude vidět hezky zformátovaný HTML kód. Kód vstupního pole, na které jsme klikli přitom bude označený. V označené části kódu tedy vyhledáme, jakou hodnotu má vlastnost name. Tuto hodnotu následně použijeme při automatickém vyplňování.

Následující příklad nastaví vstupní pole pojmenované „firstname“ na hodnotu „Jakub“.

  1. br.form['firstname'] = 'Jakub'




Hodnotu u výčtových typů formuářových elementů, mezi které patří například radio button nebo select nastavíme na list (česky seznam) obsahující hodnotu value konkrétní volby, kterou chcete vybrat.

HTML kód formuláře může obsahovat například takovýto výčtový prvek select:

  1. <select name="birthday_month">
  2.   <option value="0" selected="1">Měsíc</option>
  3.   <option value="1">led.</option>
  4.   <option value="2">únor</option>
  5.   <option value="3">břez.</option>
  6.   <option value="4">dub.</option>
  7. </select>


Pokud bychom z tohoto seznamu chtěli programově vybrat měsíc březen, musíme hodnotu výběru nastavit na ['3']. Hranaté závorky jsou použity proto, že jde o seznam. Apostrofy proto, že hodnota musí být předána jako string.

Pokud tento postup zopakujeme pro všechny vstupní pole, která je potřeba vyplnit a dáme to dohromady se zbytkem, tak bychom mohli dostat něco takovéhoto:


  1. import mechanize
  2. from random import randint
  3.  
  4. def registerFacebook(firstname, surname, sex, mail, passwd):
  5.    br = mechanize.Browser() # vytvorime si objekt Mechanize prohlizece
  6.    br.set_handle_robots(False) # nastavime, aby ignoroval soubor "robots.txt"
  7.    br.open('https://www.facebook.com/') # otevreme stranku Facebooku
  8.    br.select_form(nr=1) # vybereme, ze bydeme vyplnovat prvni formular
  9.  
  10.    # vyplnime formular
  11.    br.form['firstname'] = firstname
  12.    br.form['lastname'] = surname
  13.    br.form['reg_email__'] = mail
  14.    br.form['reg_email_confirmation__'] = mail
  15.    br.form['reg_passwd__'] = passwd
  16.  
  17.    # vybereme nahodne volby
  18.    br.form['birthday_day'] = [str(randint(1,28))]
  19.    br.form['birthday_month'] = [str(randint(1,12))]
  20.    br.form['birthday_year'] = [str(randint(1960,1995))]
  21.  
  22.    br.form['sex'] = [str(sex)]
  23.  
  24.    req = br.submit() # odesleme formular
  25.    print(req.read()) # vypiseme HTML kod stranky, co prisla v odpovedi


Nakonec už jen funkci zavoláme s požadovanými paramatr. Hodnotu „sex“ ve volání nastavíme na 1 pokud chceme zvolit pohlaví „Žena“, 2 pokud chceme zvolit možnost „Muž“.

  1. registerFacebook('jmeno', 'prijmeni', 2, 'nekdo@nekde.tld', 'heslo')


Funkce vypisuje odpověď serveru, kterou si přesměrujeme do souboru, se kterým můžeme dále pracovat v prohlížeči.

  1. $ python registerFacebook.py > file.html
  2. $ chromium file.html


Těmito příkazy otevřete odpověď na vaši registraci v prohlížeči Chromium. Odpovědí je typicky stránka žádající o potvrzení emailu.

Příště budeme programově odesílat e-maily a automaticky tak ověříme email v naší registraci.


Líbil se Vám článek?
Budeme potěšeni, pokud vás zaujme také reklamní nabídka

Social Bookmarking

     





Hodnocení/Hlasovalo: 1.56/9

1  2  3  4  5    
(známkování jako ve škole)