【问题标题】:500 Internal Server Error from third party API来自第三方 API 的 500 内部服务器错误
【发布时间】:2018-12-14 10:26:39
【问题描述】:

Python 3.6 - Scrapy 1.5

我正在抓取 John Deere 保修网页,以查看所有新的 PMP 及其到期日期。查看浏览器和网页之间的网络通信,我发现了一个 REST API,它在网页中提供数据。

现在,我正在尝试从 API 获取 json 数据,而不是抓取 javascript 页面的内容。但是,我遇到了内部服务器错误,我不知道为什么。

我正在使用scrapy来登录和捕获数据。

import scrapy

class PmpSpider(scrapy.Spider):
    name = 'pmp'
    start_urls = ['https://jdwarrantysystem.deere.com/portal/']

    def parse(self, response):

        self.log('***Form Request***')
        login ={
            'USERNAME':*******,
            'PASSWORD':*******
            }
        yield scrapy.FormRequest.from_response(
            response,
            url = 'https://registration.deere.com/servlet/com.deere.u90950.registrationlogin.view.servlets.SignInServlet',
            method = 'POST', formdata = login, callback = self.parse_pmp
        )
        self.log('***PARSE LOGIN***')

    def parse_pmp(self, response):
        self.log('***PARSE PMP***')
        cookies = response.headers.getlist('Set-Cookie')
        for cookie in cookies:
            cookie = cookie.decode('utf-8')
            self.log(cookie)
            cook = cookie.split(';')[0].split('=')[1]
            path = cookie.split(';')[1].split('=')[1]
            domain = cookie.split(';')[2].split('=')[1]
        yield scrapy.Request(
            url = 'https://jdwarrantysystem.deere.com/api/pip-products/collection',
            method = 'POST',
            cookies = {
                'SESSION':cook,
                'path':path,
                'domain':domain
            },
            headers = {
            "Accept":"application/json",
            "accounts":["201445","201264","201167","201342","201341","201221"],
            "excludedPin":"",
            "export":"",
            "language":"",
            "metric":"Y",
            "pipFilter":"OPEN",
            "pipType":["MALF","SAFT"]
            },
            meta = {'dont_redirect': True},
            callback = self.parse_pmp_list
        )

    def parse_pmp_list(self, response):
        self.log('***LISTA PMP***')
        self.log(response.body)

为什么我会收到错误消息?如何从此 API 获取数据?

2018-07-05 17:26:19 [scrapy.downloadermiddlewares.retry] DEBUG: Retrying <POST https://jdwarrantysystem.deere.com/api/pip-products/collection> (failed 1 times): 500 Internal Server Error
2018-07-05 17:26:20 [scrapy.downloadermiddlewares.retry] DEBUG: Retrying <POST https://jdwarrantysystem.deere.com/api/pip-products/collection> (failed 2 times): 500 Internal Server Error
2018-07-05 17:26:21 [scrapy.downloadermiddlewares.retry] DEBUG: Gave up retrying <POST https://jdwarrantysystem.deere.com/api/pip-products/collection> (failed 3 times): 500 Internal Server Error
2018-07-05 17:26:21 [scrapy.core.engine] DEBUG: Crawled (500) <POST https://jdwarrantysystem.deere.com/api/pip-products/collection> (referer: https://jdwarrantysystem.deere.com/portal/)
2018-07-05 17:26:21 [scrapy.spidermiddlewares.httperror] INFO: Ignoring response <500 https://jdwarrantysystem.deere.com/api/pip-products/collection>: HTTP status code is not handled or not allowed

【问题讨论】:

    标签: json python-3.x api web-scraping scrapy


    【解决方案1】:

    我发现了问题:这是一个 POST 请求,它必须有一个 json 格式的正文数据,因为与 GET 请求不同,参数不在 URI 中。请求头也需要"content-type": "application/json"。请参阅:How parameters are sent in POST requestRest POST in python。所以,编辑函数 parse_pmp:

    def parse_pmp(self, response):
            self.log('***PARSE PMP***')
            cookies = response.headers.getlist('Set-Cookie')
            for cookie in cookies:
                cookie = cookie.decode('utf-8')
                self.log(cookie)
                cook = cookie.split(';')[0].split('=')[1]
                path = cookie.split(';')[1].split('=')[1]
                domain = cookie.split(';')[2].split('=')[1]
    
            data = json.dumps({"accounts":["201445","201264","201167","201342","201341","201221"],"excludedPin":"","export":"","language":"","metric":"Y","pipFilter":"OPEN","pipType":["MALF","SAFT"]}) # <----
            yield scrapy.Request(
                url = 'https://jdwarrantysystem.deere.com/api/pip-products/collection',
                method = 'POST',
                cookies = {
                    'SESSION':cook,
                    'path':path,
                    'domain':domain
                },
                headers = {
                "Accept":"application/json",
                "content-type": "application/json" # <----
                },
                body = data, # <----
                meta = {'dont_redirect': True},
                callback = self.parse_pmp_list
            ) 
    

    一切正常!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-11-19
      • 2016-01-10
      • 2016-08-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-07-09
      • 2019-11-01
      相关资源
      最近更新 更多