""" This module implements the FormRequest class which is a more convenient class (than Request) to generate Requests based on form data. See documentation in docs/topics/request-response.rst """ from __future__ import annotations from collections.abc import Iterable, Mapping from typing import TYPE_CHECKING, Any, ClassVar, TypeAlias, cast from urllib.parse import urlencode, urljoin, urlsplit, urlunsplit from warnings import warn from parsel.csstranslator import HTMLTranslator from w3lib.html import strip_html5_whitespace from scrapy.exceptions import ScrapyDeprecationWarning from scrapy.http.request import Request from scrapy.utils.python import is_listlike, to_bytes if TYPE_CHECKING: # typing.Self requires Python 3.11 from lxml.html import ( FormElement, InputElement, MultipleSelectOptions, SelectElement, TextareaElement, ) from typing_extensions import Self from scrapy.http.response.text import TextResponse FormdataVType: TypeAlias = str | Iterable[str] FormdataKVType: TypeAlias = tuple[str, FormdataVType] FormdataType: TypeAlias = Mapping[str, FormdataVType] | Iterable[FormdataKVType] | None class FormRequest(Request): """A :class:`~scrapy.Request` subclass with a ``formdata`` parameter that url-encodes the given data and assigns it to the request, which makes it convenient to send arbitrary form data via HTTP POST or GET without an HTML ``