Edit detail for JakVyplnitFormular revision 6 of 1

6
Editor: geon
Time: 2009/07/02 11:09:25 GMT+2
Note:

changed:
-
Jak vyplnit webový formulář z Pythona
========================================


Teorie
---------

Pokud znám políčka a strukturu předem, pouze vytvořím příslušnou HTTP 
hlavičku následovanou daty s odpověďmi (viz specifikace HTTP protokolu) 
a pošlu vše přes sokety na příslušnou IP adresu a port a rozeberu 
vrácenou HTTP odpověď pro případnou kontrolu chyb.

Pokud neznám políčka a strukturu předem musím před to zařadit krok 
parsování HTML/XHTML stránky - tj. extrakce značky <form>, jeho atributů 
action a method (případně encrypted) a všech polí <input>, <textarea>, 
<file> a já nevím co všechno tam může být.


Rozbor HTML
--------------

Mějme demonstrační stránku http://spreadsheets.google.com/viewform?key=piYHG7JxUHxstW-8oPftQHQ. Nejdříve si ji skuste vypnit ručně, a podívat se na výsledky http://spreadsheets.google.com/pub?key=piYHG7JxUHxstW-8oPftQHQ (zobrazí se po 5 minutách).

Nyní si rozebereme html kod z demonstrační stránky. Přeformátováno pro lepší čitelnost::
    
    <body><h1>Anonymní dotazník</h1>
    <pre class="ss-form-desc">
    tento dotazník pomůže lidem na celém světě ;-)
          </pre>
        <p>
        </p>
        <form action="http://spreadsheets.google.com/formResponse?key=piYHG7JxUHxstW-8oPftQHQ" method="POST">
            <div class="ss-form-entry">
                <span class="ss-q-title">Jméno </span>
                <span class="ss-q-help">  </span>
                <input type="text" class="ss-q-short" name="single:7" />
            </div> 
            <div class="ss-form-entry">
                <span class="ss-q-title">Město </span>
                <span class="ss-q-help">  </span>
                <input type="text" class="ss-q-short" name="single:8" />
            </div> 
            <div class="ss-form-entry">
                <span class="ss-q-title">#  Jak se nazývá typ žloutenky - nemoc špinavých rukou? </span>
                <span class="ss-q-help">chřipka to není ;-) </span>
                <ul class="ss-choices"><li>
                    <input type="radio" value=" žloutenka typu A" name="group:2" checked="checked" /> žloutenka typu A</li> <li>
                    <input type="radio" value=" žloutenka typu B" name="group:2" /> žloutenka typu B</li> <li>
                    <input type="radio" value=" žloutenka typu C" name="group:2" /> žloutenka typu C</li>
                </ul>
            </div> 
            <div class="ss-form-entry">
                <span class="ss-q-title">Jaké příznaky se nevyskytují u infarktu myokardu?  </span>
                <span class="ss-q-help">   </span>
                <ul class="ss-choices"><li>
                    <input type="checkbox" value="premenstruční syndrom" name="group:3" />premenstruční syndrom</li> <li>
                    <input type="checkbox" value="zánět močového měchýře" name="group:3" />zánět močového měchýře</li> <li>
                    <input type="checkbox" value="bolest na hrudi" name="group:3" />bolest na hrudi</li>
                </ul>
            </div> 
            <div class="ss-form-entry">
                <span class="ss-q-title">Napište něco o sobě  </span>
                <span class="ss-q-help">jen tak ...   </span>
                <textarea class="ss-q-long" name="single:5" rows="8" cols="75"></textarea>
            </div>
            <p>
            </p>
            <input type="submit" value="Odeslat" />
        </form>
        <span class="ss-powered-by">používá technologii Dokumenty Google
        </span>
        <p>
        </p><small>
            <a href="http://www.google.com/accounts/TOS">Smluvní podmínky služby</a>-
            <a href="http://www.google.com/google-d-s/terms.html">Další smluvní podmínky</a></small>
    </body>
    
- na řádce 6 vidíme, jaká stránka se volá, když se  formulář odesílá, ten použijeme i my. Tedy bude to !http://spreadsheets.google.com/formResponse?key=piYHG7JxUHxstW-8oPftQHQ
- je tam 5 polí na vyplnění, každé se nějak jmenuje. Hledejte vždy parametr name= ... :
 - Jméno = single:7 
 - Město = single:8
 - Jak se nazývá typ žloutenky - nemoc špinavých rukou? = group:2 (je napsáno u jednotlivých položek)
 - Jaké příznaky se nevyskytují u infarktu myokardu? = group:3
 - Napište něco o sobě = single:5
 
Možná řešení
--------------------

urlib
.......

::
    
    # -*- coding: utf-8 -*- 
    import urllib, urllib2
    
    adresa= "http://spreadsheets.google.com/formResponse?key=piYHG7JxUHxstW-8oPftQHQ"
    parametry= {
        "single:7": "Bystroushaak",
        "single:8": "Litomerice",
        "group:2":  "Žloutenka typu B",
        "group:3":  "Zánět močového měchýře",
        "single:5": "Tento formular byl vyplnen scriptem od Bystroushaaka!"}
    
    params= urllib.urlencode(parametry)  # Prekoduje parametry do tvaru vhodneho pro odeslani 
    req= urllib2.Request(adresa, params) # Vytvori request, coz je smichanina adresy a parametru, pripadne i hlavicek
    
    spojeni = urllib2.urlopen(req)       # Otevre
    spojeni.read()                       # a nacte stranku
    spojeni.close() 

Program je jistě možno doplnit o načítání jednotlivých parametrů přes raw_input() nebo pomocí jakéhokoliv GUI, ale to si jistě laskavý čtenář udělá sám nebo se zeptá v konferenci.
    

zope.testbrowser
.......................

Stáhněte a nainstalujte modul z http://pypi.python.org/pypi/zope.testbrowser - úplně dole je soubor ke stažení. Kod programu::

    # -*- coding: utf-8 -*-
    
    from zope.testbrowser.browser import Browser
    browser = Browser('http://spreadsheets.google.com/viewform?key=piYHG7JxUHxstW-8oPftQHQ')
    
    form = browser.getForm()
    
    # ukázka získání možných voleb
    c = form.getControl(name='group:2')
    print c.options
    
    # vyplnění některých polí
    c.getControl(value=' žloutenka typu C').selected = True 
    form.getControl(name='single:7').value = 'Honza Nový'
    form.getControl(name='single:8').value = 'Nová Ves'
    form.getControl(name='group:3').value = ['premenstruční syndrom', 'zánět močového měchýře']
    form.getControl(name='single:5').value = 'pěkný příklad'
    
    form.submit()
    print browser.contents 


Možné trable
,,,,,,,,,,,,,,,

Je možné, že časem narazíte na problém se souborem robots.txt. Poznáte to tak, že vám nepůjde načíst stránka a jako chybu bude Python hlásit toto:: 

 Traceback (most recent call last):
  File "<stdin>", line 3, in <module>
  File "c:\python25\lib\site-packages\zope.testbrowser-3.4.2-py2.5.egg\zope\test browser\browser.py", line 224, in open
    self.mech_browser.open(url, data)
  File "build\bdist.win32\egg\mechanize\_mechanize.py", line 203, in open
  File "build\bdist.win32\egg\mechanize\_mechanize.py", line 254, in _mech_open
 mechanize._response.httperror_seek_wrapper: HTTP Error 403: request disallowed by robots.txt

Existují dva způsoby jak to vyřešit:

1. dočasná úprava konfigurace objektu Browser::

 >>> >>> from zope.testbrowser.browser import Browser
 >>> >>> browser= Browser()
 >>> >>> browser.mech_browser.set_handle_robots(False)

2. trvalá úprava:

- otevřete si soubor ``Python25\Lib\site-packages\zope.testbrowser-3.4.2-py2.5.egg\zope\testbrowser\browser.py``
- přidejte 160 řádek v tomto tvaru: self.mech_browser.set_handle_robots(False)
- výsledek by měl vypadat nějak takto: http://img84.imageshack.us/my.php?image=broyu3.jpg


!ClientFrom
....................
http://wwwsearch.sourceforge.net/ClientForm/

Jak vyplnit webový formulář z Pythona

Teorie

Pokud znám políčka a strukturu předem, pouze vytvořím příslušnou HTTP hlavičku následovanou daty s odpověďmi (viz specifikace HTTP protokolu) a pošlu vše přes sokety na příslušnou IP adresu a port a rozeberu vrácenou HTTP odpověď pro případnou kontrolu chyb.

Pokud neznám políčka a strukturu předem musím před to zařadit krok parsování HTML/XHTML stránky - tj. extrakce značky <form>, jeho atributů action a method (případně encrypted) a všech polí <input>, <textarea>, <file> a já nevím co všechno tam může být.

Rozbor HTML

Mějme demonstrační stránku http://spreadsheets.google.com/viewform?key=piYHG7JxUHxstW-8oPftQHQ. Nejdříve si ji skuste vypnit ručně, a podívat se na výsledky http://spreadsheets.google.com/pub?key=piYHG7JxUHxstW-8oPftQHQ (zobrazí se po 5 minutách).

Nyní si rozebereme html kod z demonstrační stránky. Přeformátováno pro lepší čitelnost:

<body><h1>Anonymní dotazník</h1>
<pre class="ss-form-desc">
tento dotazník pomůže lidem na celém světě ;-)
      </pre>
    <p>
    </p>
    <form action="http://spreadsheets.google.com/formResponse?key=piYHG7JxUHxstW-8oPftQHQ" method="POST">
        <div class="ss-form-entry">
            <span class="ss-q-title">Jméno </span>
            <span class="ss-q-help">  </span>
            <input type="text" class="ss-q-short" name="single:7" />
        </div>
        <div class="ss-form-entry">
            <span class="ss-q-title">Město </span>
            <span class="ss-q-help">  </span>
            <input type="text" class="ss-q-short" name="single:8" />
        </div>
        <div class="ss-form-entry">
            <span class="ss-q-title">#  Jak se nazývá typ žloutenky - nemoc špinavých rukou? </span>
            <span class="ss-q-help">chřipka to není ;-) </span>
            <ul class="ss-choices"><li>
                <input type="radio" value=" žloutenka typu A" name="group:2" checked="checked" /> žloutenka typu A</li> <li>
                <input type="radio" value=" žloutenka typu B" name="group:2" /> žloutenka typu B</li> <li>
                <input type="radio" value=" žloutenka typu C" name="group:2" /> žloutenka typu C</li>
            </ul>
        </div>
        <div class="ss-form-entry">
            <span class="ss-q-title">Jaké příznaky se nevyskytují u infarktu myokardu?  </span>
            <span class="ss-q-help">   </span>
            <ul class="ss-choices"><li>
                <input type="checkbox" value="premenstruční syndrom" name="group:3" />premenstruční syndrom</li> <li>
                <input type="checkbox" value="zánět močového měchýře" name="group:3" />zánět močového měchýře</li> <li>
                <input type="checkbox" value="bolest na hrudi" name="group:3" />bolest na hrudi</li>
            </ul>
        </div>
        <div class="ss-form-entry">
            <span class="ss-q-title">Napište něco o sobě  </span>
            <span class="ss-q-help">jen tak ...   </span>
            <textarea class="ss-q-long" name="single:5" rows="8" cols="75"></textarea>
        </div>
        <p>
        </p>
        <input type="submit" value="Odeslat" />
    </form>
    <span class="ss-powered-by">používá technologii Dokumenty Google
    </span>
    <p>
    </p><small>
        <a href="http://www.google.com/accounts/TOS">Smluvní podmínky služby</a>-
        <a href="http://www.google.com/google-d-s/terms.html">Další smluvní podmínky</a></small>
</body>
  • na řádce 6 vidíme, jaká stránka se volá, když se formulář odesílá, ten použijeme i my. Tedy bude to http://spreadsheets.google.com/formResponse?key=piYHG7JxUHxstW-8oPftQHQ
  • je tam 5 polí na vyplnění, každé se nějak jmenuje. Hledejte vždy parametr name= ... :
  • Jméno = single:7
  • Město = single:8
  • Jak se nazývá typ žloutenky - nemoc špinavých rukou? = group:2 (je napsáno u jednotlivých položek)
  • Jaké příznaky se nevyskytují u infarktu myokardu? = group:3
  • Napište něco o sobě = single:5

Možná řešení

urlib

# -*- coding: utf-8 -*-
import urllib, urllib2

adresa= "http://spreadsheets.google.com/formResponse?key=piYHG7JxUHxstW-8oPftQHQ"
parametry= {
    "single:7": "Bystroushaak",
    "single:8": "Litomerice",
    "group:2":  "Žloutenka typu B",
    "group:3":  "Zánět močového měchýře",
    "single:5": "Tento formular byl vyplnen scriptem od Bystroushaaka!"}

params= urllib.urlencode(parametry)  # Prekoduje parametry do tvaru vhodneho pro odeslani
req= urllib2.Request(adresa, params) # Vytvori request, coz je smichanina adresy a parametru, pripadne i hlavicek

spojeni = urllib2.urlopen(req)       # Otevre
spojeni.read()                       # a nacte stranku
spojeni.close()

Program je jistě možno doplnit o načítání jednotlivých parametrů přes raw_input() nebo pomocí jakéhokoliv GUI, ale to si jistě laskavý čtenář udělá sám nebo se zeptá v konferenci.

zope.testbrowser

Stáhněte a nainstalujte modul z http://pypi.python.org/pypi/zope.testbrowser - úplně dole je soubor ke stažení. Kod programu:

# -*- coding: utf-8 -*-

from zope.testbrowser.browser import Browser
browser = Browser('http://spreadsheets.google.com/viewform?key=piYHG7JxUHxstW-8oPftQHQ')

form = browser.getForm()

# ukázka získání možných voleb
c = form.getControl(name='group:2')
print c.options

# vyplnění některých polí
c.getControl(value=' žloutenka typu C').selected = True
form.getControl(name='single:7').value = 'Honza Nový'
form.getControl(name='single:8').value = 'Nová Ves'
form.getControl(name='group:3').value = ['premenstruční syndrom', 'zánět močového měchýře']
form.getControl(name='single:5').value = 'pěkný příklad'

form.submit()
print browser.contents

Možné trable

Je možné, že časem narazíte na problém se souborem robots.txt. Poznáte to tak, že vám nepůjde načíst stránka a jako chybu bude Python hlásit toto:

Traceback (most recent call last):
 File "<stdin>", line 3, in <module>
 File "c:\python25\lib\site-packages\zope.testbrowser-3.4.2-py2.5.egg\zope\test browser\browser.py", line 224, in open
   self.mech_browser.open(url, data)
 File "build\bdist.win32\egg\mechanize\_mechanize.py", line 203, in open
 File "build\bdist.win32\egg\mechanize\_mechanize.py", line 254, in _mech_open
mechanize._response.httperror_seek_wrapper: HTTP Error 403: request disallowed by robots.txt

Existují dva způsoby jak to vyřešit:

  1. dočasná úprava konfigurace objektu Browser:
>>> >>> from zope.testbrowser.browser import Browser
>>> >>> browser= Browser()
>>> >>> browser.mech_browser.set_handle_robots(False)
  1. trvalá úprava:
  • otevřete si soubor Python25\Lib\site-packages\zope.testbrowser-3.4.2-py2.5.egg\zope\testbrowser\browser.py
  • přidejte 160 řádek v tomto tvaru: self.mech_browser.set_handle_robots(False)
  • výsledek by měl vypadat nějak takto: http://img84.imageshack.us/my.php?image=broyu3.jpg