Scrapy框架-爬虫方法-发送POST

Scrapy框架-爬虫方法-发送POST,第1张

Scrapy框架-爬虫方法-发送POST

对于蜘蛛抓取周期是这样的:

    您首先生成初始请求以抓取第一个 URL,并指定一个回调函数,以使用从这些请求下载的响应调用。

    第一个要执行的请求是通过调用 start_requests()(默认情况下)Request为 中指定的 URL 生成start_urls的 parse方法和作为请求的回调函数的方法获得的。

    在回调函数中,您解析响应并返回项目对象或这些对象的可迭代对象。这些请求还将包含一个回调,然后将由 Scrapy 下载,然后由指定的回调处理它们的响应。

    在回调函数中,您解析页面内容,通常使用选择器(但您也可以使用 BeautifulSoup、lxml 或您喜欢的任何机制)并使用解析的数据生成项目。

    最后,从蜘蛛返回的项目通常会保存到数据库或使用Feed 导出写入文件。

即使这个循环适用于任何种类的蜘蛛,也有不同种类的默认蜘蛛捆绑到 Scrapy 中用于不同的目的。我们将在这里讨论这些类型

一、start_requests ()

此方法必须返回一个迭代器,其中包含要为该蜘蛛爬行的第一个请求

如果您想更改用于开始抓取域的请求,这是覆盖的方法。例如,如果您需要首先使用 POST 请求登录,您可以执行以下 *** 作:

class MySpider(scrapy.Spider):
    name = 'myspider'

    def start_requests(self):
        return [scrapy.FormRequest("http://www.example.com/login",
                                   formdata={'user': 'john', 'pass': 'secret'},
                                   callback=self.logged_in)]

    def logged_in(self, response):
        pass
二、allowed_domains

包含允许此蜘蛛抓取的域的可选字符串列表。OffsiteMiddleware如果启用,则不会遵循不属于此列表中指定的域名(或其子域)的 URL 请求 。

假设您的目标网址是https://www.example.com/1.html,然后添加'example.com'到列表中。

三、发送POST请求

官方推荐的 Using FormRequest to send data via HTTP POST

return [FormRequest(url="http://www.example.com/post/action",
                    formdata={'name': 'John Doe', 'age': '27'},
                    callback=self.after_post)]

这里使用的是FormRequest,并使用formdata传递参数,看到这里也是一个字典。

但是,超级坑的一点来了,使用这种方法发送请求,怎么发都会出问题,返回的数据一直都不是我想要的

payload = {‘password’ : '123123'}
return scrapy.Request(url, body=json.dumps(payload), method='POST', headers={'Content-Type': 'application/json'},)

我们看一下他的源码

class FormRequest(Request):

    def __init__(self, *args, **kwargs):
        formdata = kwargs.pop('formdata', None)
        if formdata and kwargs.get('method') is None:
            kwargs['method'] = 'POST'

        super(FormRequest, self).__init__(*args, **kwargs)

        if formdata:
            items = formdata.items() if isinstance(formdata, dict) else formdata
            querystr = _urlencode(items, self.encoding)
            if self.method == 'POST':
                self.headers.setdefault(b'Content-Type', b'application/x-www-form-urlencoded')
                self._set_body(querystr)
            else:
                self._set_url(self.url + ('&' if '?' in self.url else '?') + querystr)
            ###


def _urlencode(seq, enc):
    values = [(to_bytes(k, enc), to_bytes(v, enc))
              for k, vs in seq
              for v in (vs if is_listlike(vs) else [vs])]
    return urlencode(values, doseq=1)

最终我们传递的{‘key’: ‘value’, ‘k’: ‘v’}会被转化为’key=value&k=v’ 并且默认的method是POST,所以直接这样使用会出错

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zaji/5719676.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-18
下一篇 2022-12-18

发表评论

登录后才能评论

评论列表(0条)

保存