reuse LxmlDocument in FormRequest. #111

This commit is contained in:
Daniel Graña 2012-04-13 15:41:58 -03:00
parent 9e10abcc43
commit a11ef7fba7
2 changed files with 10 additions and 10 deletions

View File

@ -6,9 +6,7 @@ See documentation in docs/topics/request-response.rst
"""
import urllib
from lxml import html
import lxml.html
from scrapy.http.request import Request
from scrapy.utils.python import unicode_to_str
@ -34,6 +32,7 @@ class FormRequest(Request):
@classmethod
def from_response(cls, response, formname=None, formnumber=0, formdata=None,
clickdata=None, dont_click=False, **kwargs):
from scrapy.selector.lxmldocument import LxmlDocument
if not hasattr(formdata, "items"):
try:
formdata = dict(formdata) if formdata else {}
@ -41,28 +40,29 @@ class FormRequest(Request):
raise ValueError('formdata should be a dict or iterable of tuples')
kwargs.setdefault('encoding', response.encoding)
hxs = html.fromstring(response.body_as_unicode(), base_url=response.url)
form = _get_form(hxs, formname, formnumber, response)
root = LxmlDocument(response, lxml.html.HTMLParser)
form = _get_form(root, formname, formnumber, response)
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(hxs, formname, formnumber, response):
def _get_form(root, formname, formnumber, response):
"""
Uses all the passed arguments to get the required form
element
"""
if not hxs.forms:
if not root.forms:
raise ValueError("No <form> element found in %s" % response)
if formname is not None:
f = hxs.xpath('//form[@name="%s"]' % formname)
f = root.xpath('//form[@name="%s"]' % formname)
if f:
return f[0]
@ -70,7 +70,7 @@ def _get_form(hxs, formname, formnumber, response):
# or invalid
if formnumber is not None:
try:
form = hxs.forms[formnumber]
form = root.forms[formnumber]
except IndexError:
raise IndexError("Form number %d not found in %s" %
(formnumber, response))

View File

@ -18,7 +18,7 @@ def _factory(response, parser_cls):
class LxmlDocument(object_ref):
cache = weakref.WeakKeyDictionary()
__slots__ = ['xmlDoc', 'xpathContext', '__weakref__']
__slots__ = ['__weakref__']
def __new__(cls, response, parser=etree.HTMLParser):
cache = cls.cache.setdefault(response, {})