""" This module implements the FormRequest class which is a more covenient class (than Request) to generate Requests based on form data. See documentation in docs/topics/request-response.rst """ import urllib import lxml.html from scrapy.http.request import Request from scrapy.utils.python import unicode_to_str class FormRequest(Request): def __init__(self, *args, **kwargs): formdata = kwargs.pop('formdata', None) if formdata and kwargs.get('method') is None: kwargs['method'] = 'POST' super(FormRequest, self).__init__(*args, **kwargs) if formdata: items = formdata.iteritems() if isinstance(formdata, dict) else formdata querystr = _urlencode(items, self.encoding) if self.method == 'POST': self.headers.setdefault('Content-Type', 'application/x-www-form-urlencoded') self._set_body(querystr) else: self._set_url(self.url + ('&' if '?' in self.url else '?') + querystr) @classmethod def from_response(cls, response, formname=None, formnumber=0, formdata=None, clickdata=None, dont_click=False, **kwargs): kwargs.setdefault('encoding', response.encoding) form = _get_form(response, formname, formnumber) formdata = _get_inputs(form, formdata, dont_click, clickdata, response) url = form.action or form.base_url return cls(url, method=form.method, formdata=formdata, **kwargs) def _urlencode(seq, enc): values = [(unicode_to_str(k, enc), unicode_to_str(v, enc)) for k, vs in seq for v in (vs if hasattr(vs, '__iter__') else [vs])] return urllib.urlencode(values, doseq=1) def _get_form(response, formname, formnumber): """Find the form element """ from scrapy.selector.lxmldocument import LxmlDocument root = LxmlDocument(response, lxml.html.HTMLParser) if not root.forms: raise ValueError("No