MCPcopy
hub / github.com/scrapy/scrapy / _get_clickable

Function _get_clickable

scrapy/http/request/form.py:229–276  ·  view source on GitHub ↗

Returns the clickable element specified in clickdata, if the latter is given. If not, it returns the first clickable element found

(
    clickdata: dict[str, str | int] | None, form: FormElement
)

Source from the content-addressed store, hash-verified

227
228
229def _get_clickable(
230 clickdata: dict[str, str | int] | None, form: FormElement
231) -> tuple[str, str] | None:
232 """
233 Returns the clickable element specified in clickdata,
234 if the latter is given. If not, it returns the first
235 clickable element found
236 """
237 clickables = list(
238 form.xpath(
239 'descendant::input[re:test(@type, "^(submit|image)$", "i")]'
240 '|descendant::button[not(@type) or re:test(@type, "^submit$", "i")]',
241 namespaces={"re": "http://exslt.org/regular-expressions"},
242 )
243 )
244 if not clickables:
245 return None
246
247 # If we don't have clickdata, we just use the first clickable element
248 if clickdata is None:
249 el = clickables[0]
250 return (el.get("name"), el.get("value") or "")
251
252 # If clickdata is given, we compare it to the clickable elements to find a
253 # match. We first look to see if the number is specified in clickdata,
254 # because that uniquely identifies the element
255 nr = clickdata.get("nr", None)
256 if nr is not None:
257 assert isinstance(nr, int)
258 try:
259 el = list(form.inputs)[nr]
260 except IndexError:
261 pass
262 else:
263 return (cast("str", el.get("name")), el.get("value") or "")
264
265 # We didn't find it, so now we build an XPath expression out of the other
266 # arguments, because they can be used as such
267 xpath = ".//*" + "".join(f'[@{k}="{v}"]' for k, v in clickdata.items())
268 el = form.xpath(xpath)
269 if len(el) == 1:
270 return (el[0].get("name"), el[0].get("value") or "")
271 if len(el) > 1:
272 raise ValueError(
273 f"Multiple elements found ({el!r}) matching the "
274 f"criteria in clickdata: {clickdata!r}"
275 )
276 raise ValueError(f"No clickable element matching clickdata: {clickdata!r}")

Callers 1

_get_inputsFunction · 0.85

Calls 4

itemsMethod · 0.80
xpathMethod · 0.45
getMethod · 0.45
joinMethod · 0.45

Tested by

no test coverage detected