Response

方法

请求响应 提供了自带的以下方法

  • xpath
  • css
  • re
  • re_first
  • bs4(默认解析器:lxml)
  • urljoin:合并 url,可以手动使用(默认会自动处理)

示例

def parse(self, request, response) -> None:
    """
    解析函数

    :param request:
    :param response:
    :return:
    """
    response.bs4.find()
    response.re()
    response.re_first()
    response.xpath().extract()
    response.xpath().extract_first()

自定义请求器

步骤

  • 定义 downloader 类并继承 palp.network.ResponseDownloader
  • 实现 response 方法,并返回
  • 定义 resoonse 类并继承 palp.network.Response
  • 更改设置(全局)
  • 请求添加参数(局部)

定义 downloader 类

继承 palp.network.ResponseDownloader

注意:

  • Request 类的参数都是 requests 的,但是 ResponseDownloader 不会接收全部参数,所以这里使用了 self.kwargs
  • ResponseDownloader 接收的参数可以通过 command 字典进行接收

这里以 requests 举例

  • 需要实现 keep_session 时使用 session
  • keep_cookie 时使用 cookie_jar
  • 主要看是看你具体使用什么去响应,具体需求具体构造
  • 最后要返回响应
"""
    requests 请求器
"""
import requests
from requests.adapters import HTTPAdapter
from palp.network.downloader import ResponseDownloader


class ResponseDownloaderByRequests(ResponseDownloader):
    """
        适用于 requests 的请求器
    """
    SESSION = None

    def __new__(cls, *args, **kwargs):
        """
        requests 设置 session

        :param args:
        :param kwargs:
        """
        if cls.SESSION is None:
            cls.SESSION = requests.Session()
            # 同一 session 默认连接池、最大连接数都是 10,这里改为 1000
            cls.SESSION.mount("http", HTTPAdapter(pool_connections=1000, pool_maxsize=1000))

        return object.__new__(cls)

    def response(self):
        """
        处理响应并返回

        :return:
        """
        # 获取请求器
        if self.keep_session:
            request = self.session
        else:
            request = requests

        # 是否保持 cookie
        if not self.keep_session and self.keep_cookie:
            self.cookies = self.cookie_jar

        return request.request(
            url=self.url,
            method=self.method,
            params=self.params,
            data=self.data,
            headers=self.headers,
            cookies=self.cookies,
            timeout=self.timeout,
            proxies=self.proxies,
            json=self.json,
            **self.kwargs
        )

定义 Response 类

继承 palp.network.Response 这里以 requests 举例

  • 实现下面的方法,其中 text、cookies、url 是必须实现的
  • 其余的可以根据要什么实现什么
"""
    适用于 requests 的响应解析器
"""
from palp.network.response import Response


class RequestsResponse(Response):
    """
        适用于 requests 的响应解析器
    """

    def __init__(self, resp):
        super().__init__(resp)

    @property
    def text(self) -> str:
        return self.content.decode(self.encoding)

    @property
    def content(self) -> bytes:
        return self.response.content

    def json(self, **kwargs) -> dict:
        return self.response.json(**kwargs)

    @property
    def status_code(self) -> int:
        return self.response.status_code

    @property
    def cookies(self) -> dict:
        return self.response.cookies.get_dict()

    @property
    def headers(self) -> dict:
        return dict(self.response.headers)

    @property
    def url(self) -> str:
        return self.response.url

    @property
    def history(self) -> list:
        """
        响应 url

        :return:
        """
        return self.response.history

    @property
    def links(self):
        """

        :return:
        """
        return self.response.links

全局使用

settings 更改

RESPONSE_DOWNLOADER = 'palp.network.downloader_requests.ResponseDownloaderByRequests'  # 请求器,这里默认是 requests
RESPONSE_DOWNLOADER_PARSER = 'palp.network.response_requests.RequestsResponse'  # 解析器,这里默认是 requests

局部使用

引入,并在 yield 请求的时候直接传递即可
注意:不需要实例化

yield RequestGet(
    downloader=ResponseDownloaderByRequests,
    downloader_parser=RequestsResponse
)