【问题标题】:Scrapy ajax POST request not working, though working in PostmanScrapy ajax POST 请求不起作用,尽管在 Postman 中工作
【发布时间】:2017-09-01 22:15:32
【问题描述】:

我正在实施一个抓取蜘蛛来抓取包含房地产报价的网站。该站点包含房地产经纪人的电话号码,可以通过 ajax 发布请求检索该电话号码。 scrapy 产生的请求从服务器返回错误,而从 Postman 发送的相同请求返回所需的数据。

这是网站网址:https://www.otodom.pl/oferta/piekne-mieszkanie-na-mokotowie-do-wynajecia-ID3ezHA.html

我使用 chrome 开发工具中的网络选项卡记录了请求。 ajax请求的url为:enter link description here发送请求所需的数据是页面源中包含的CSRFtoken,它会周期性的变化。在 Postman 中,仅提供 CSRFtoken 作为表单数据给出了预期的答案。

这就是我在 scrapy 中构造请求的方式:

    token_input = response.xpath('//script[contains(./text(), "csrf")]/text()').extract_first()
    csrf_token = token_input[23:-4]

    offerID_input = response.xpath('//link[@rel="canonical"]/@href').extract_first()
    offerID = (offerID_input[:-5])[-7:]

    form_data = {'CSRFToken' : csrf_token}

    request_to_send = scrapy.Request(url='https://www.otodom.pl/ajax/misc/contact/phone/3ezHA/', headers = {"Content-Type" : "application/x-www-form-urlencoded"}, method="POST", body=urllib.urlencode(form_data), callback = self.get_phone)

    yield request_to_send

不幸的是,我收到了一个错误,尽管一切都应该没问题。有谁知道可能是什么问题?是否可能与编码有关?该网站使用 utf-8。

【问题讨论】:

    标签: ajax post scrapy postman


    【解决方案1】:

    您可以在页面源中找到令牌:

    <script type="text/javascript">
    var csrfToken = '0ec80a520930fb2006e4a3e5a4beb9f7e0d6f0de264d15f9c87b572a9b33df0a';
    </script>
    

    你可以用这个正则表达式很容易地得到它:

    re.findall("csrfToken = '(.+?)'", response.body)
    

    要获得全部内容,您可以使用 scrapy 的 FormRequest,它可以为您发出正确的发布请求:

    def parse(self, response):
        token = re.findall("csrfToken = '(.+?)'", response.body)[0]
        yield FormRequest('https://www.otodom.pl/ajax/misc/contact/phone/3ezHA/',
                          formdata={'CSRFToken': token},
                          callback=self.parse_phone)
    
    def parse_phone(self, response):
        print(response.body)
        #'{"value":"515 174 616"}'
    

    您可以通过插入inspect_response 调用并查看request 对象来调试您的scrapy 请求:

    def parse_phone(self, response):
        from scrapy.shell import inspect_response
        inspect_response(response, self)
        # shell opens up here and spider is put on pause
        # now check `request.body` and `request.headers`, match those to what you see in your browser 
    

    【讨论】:

    • 我在获取令牌方面没有问题,我什至发布了获取它的代码。问题出在请求上 - 它包含所有需要的数据并返回错误。
    • @jkwi 哦,对不起,我看错了你的问题。请参阅我的编辑以获取完整答案。
    • 感谢您的更新,它的工作就像一个魅力。干杯。
    猜你喜欢
    • 2021-12-24
    • 2013-06-01
    • 1970-01-01
    • 2021-02-27
    • 2023-04-06
    • 1970-01-01
    • 2021-10-05
    • 2019-12-05
    • 2016-11-05
    相关资源
    最近更新 更多