mirror of https://github.com/scrapy/scrapy.git
more lxml form fixes and test cases. #111
* Do not treat "coord" attribute specially, just pass "NN,NN" as clickdata value * Raise explicit ValueError if not clickable is found * Fix bug looking for clickeables trough xpath when there is more than one form * Test from_response with multiple clickdata
This commit is contained in:
parent
32b9f788be
commit
ee1f7847a4
|
|
@ -118,17 +118,14 @@ def _get_clickable(clickdata, clickables, form):
|
|||
|
||||
# We didn't find it, so now we build an XPath expression out of the other
|
||||
# arguments, because they can be used as such
|
||||
xpath_pred = []
|
||||
for k, v in clickdata.items():
|
||||
if k == 'coord':
|
||||
v = ','.join(str(c) for c in v)
|
||||
xpath_pred.append('[@%s="%s"]' % (k, v))
|
||||
|
||||
xpath_expr = '//*%s' % ''.join(xpath_pred)
|
||||
el = form.xpath(xpath_expr)
|
||||
if len(el) > 1:
|
||||
xpath = u'.//*' + \
|
||||
u''.join(u'[@%s="%s"]' % tuple(c) for c in clickdata.iteritems())
|
||||
el = form.xpath(xpath)
|
||||
if len(el) == 1:
|
||||
return (el[0].name, el[0].value)
|
||||
elif len(el) > 1:
|
||||
raise MultipleElementsFound("Multiple elements found (%r) "
|
||||
"matching the criteria in clickdata: %r"
|
||||
% (el, clickdata))
|
||||
else:
|
||||
return (el[0].name, el[0].value)
|
||||
raise ValueError('No clickeable element matching clickdata')
|
||||
|
|
|
|||
|
|
@ -306,6 +306,59 @@ class FormRequestTest(RequestTest):
|
|||
self.assertEqual(urlargs['one'], ['1'])
|
||||
self.assertEqual(urlargs['two'], ['2'])
|
||||
|
||||
def test_from_response_multiple_clickdata(self):
|
||||
respbody = """
|
||||
<form action="get.php" method="GET">
|
||||
<input type="submit" name="clickeable" value="clicked1">
|
||||
<input type="submit" name="clickeable" value="clicked2">
|
||||
<input type="hidden" name="one" value="clicked1">
|
||||
<input type="hidden" name="two" value="clicked2">
|
||||
</form>
|
||||
"""
|
||||
response = HtmlResponse("http://www.example.com/this/list.html", body=respbody)
|
||||
r1 = self.request_class.from_response(response, \
|
||||
clickdata={'name': 'clickeable', 'value': 'clicked2'})
|
||||
urlargs = cgi.parse_qs(urlparse(r1.url).query)
|
||||
self.assertEqual(urlargs['clickeable'], ['clicked2'])
|
||||
self.assertEqual(urlargs['one'], ['clicked1'])
|
||||
self.assertEqual(urlargs['two'], ['clicked2'])
|
||||
|
||||
def test_from_response_unicode_clickdata(self):
|
||||
body = u"""
|
||||
<form action="get.php" method="GET">
|
||||
<input type="submit" name="price in \u00a3" value="\u00a3 1000">
|
||||
<input type="submit" name="price in \u20ac" value="\u20ac 2000">
|
||||
<input type="hidden" name="poundsign" value="\u00a3">
|
||||
<input type="hidden" name="eurosign" value="\u20ac">
|
||||
</form>
|
||||
"""
|
||||
response = HtmlResponse("http://www.example.com", body=body, \
|
||||
encoding='utf-8')
|
||||
r1 = self.request_class.from_response(response, \
|
||||
clickdata={'name': u'price in \u00a3'})
|
||||
urlargs = cgi.parse_qs(urlparse(r1.url).query)
|
||||
self.assertTrue(urlargs[u'price in \u00a3'.encode('utf-8')])
|
||||
|
||||
def test_from_response_multiple_forms_clickdata(self):
|
||||
body = u"""
|
||||
<form name="form1">
|
||||
<input type="submit" name="clickeable" value="clicked">
|
||||
<input type="hidden" name="field1" value="value1">
|
||||
</form>
|
||||
<form name="form2">
|
||||
<input type="submit" name="clickeable" value="clicked">
|
||||
<input type="hidden" name="field2" value="value2">
|
||||
</form>
|
||||
"""
|
||||
res = HtmlResponse("http://example.com", body=body, encoding='utf-8')
|
||||
req = self.request_class.from_response(res, \
|
||||
formname='form2', \
|
||||
clickdata={'name': 'clickeable'})
|
||||
urlargs = cgi.parse_qs(urlparse(req.url).query)
|
||||
self.assertEqual(urlargs['clickeable'], ['clicked'])
|
||||
self.assertEqual(urlargs['field2'], ['value2'])
|
||||
self.assertFalse('field1' in urlargs, urlargs)
|
||||
|
||||
def test_from_response_dont_click(self):
|
||||
respbody = """
|
||||
<form action="get.php" method="GET">
|
||||
|
|
@ -336,6 +389,17 @@ class FormRequestTest(RequestTest):
|
|||
response,
|
||||
clickdata={'type': 'submit'})
|
||||
|
||||
def test_from_response_non_matching_clickdata(self):
|
||||
body = """
|
||||
<form>
|
||||
<input type="submit" name="clickeable" value="clicked">
|
||||
</form>
|
||||
"""
|
||||
res = HtmlResponse("http://example.com", body=body)
|
||||
self.assertRaises(ValueError,
|
||||
self.request_class.from_response, res,
|
||||
clickdata={'nonexistent': 'notme'})
|
||||
|
||||
def test_from_response_errors_noform(self):
|
||||
respbody = """<html></html>"""
|
||||
response = HtmlResponse("http://www.example.com/lala.html", body=respbody)
|
||||
|
|
|
|||
Loading…
Reference in New Issue