как сделать запрос POST в Scrapy, который требует полезной нагрузки запроса - PullRequest
0 голосов
/ 07 октября 2019

Я пытаюсь проанализировать данные с этого веб-сайта .
В разделе «Сеть» элемента проверки я нашел эту ссылку https://busfor.pl/api/v1/searches, которая используется для запроса POST, который возвращает JSON. интересует.
Но для выполнения этого POST-запроса есть запрос Payload с каким-то словарем.
Я предполагал, что это как обычные форм-данные, которые мы используем для создания FormRequest в scrapy, но он возвращает ошибку 403.

Я уже попробовал следующее.

url = "https://busfor.pl/api/v1/searches"
formdata = {"from_id" : d_id
                ,"to_id" : a_id
                ,"on" : '2019-10-10'
                ,"passengers" : 1
                ,"details" : []
}
yield scrapy.FormRequest(url, callback=self.parse, formdata=formdata)

Это возвращает 403 Ошибка
Я также попробовал это, сославшись на один из постов StackOverflow.

url = "https://busfor.pl/api/v1/searches"
payload = [{"from_id" : d_id
                ,"to_id" : a_id
                ,"on" : '2019-10-10'
                ,"passengers" : 1
                ,"details" : []
}]
yield scrapy.Request(url, self.parse, method = "POST", body = json.dumps(payload))

Но даже это возвращает ту же ошибку.
Может кто-то помочьменя. выяснить, как анализировать необходимые данные с помощью Scrapy.

1 Ответ

0 голосов
/ 07 октября 2019

Способ отправки POST-запросов с данными json более поздний, но вы передаете неправильный json на сайт, он ожидает словарь, а не список словарей. Поэтому вместо:

payload = [{"from_id" : d_id
                ,"to_id" : a_id
                ,"on" : '2019-10-10'
                ,"passengers" : 1
                ,"details" : []
}]

Вы должны использовать:

payload = {"from_id" : d_id
                ,"to_id" : a_id
                ,"on" : '2019-10-10'
                ,"passengers" : 1
                ,"details" : []
}

Еще одна вещь, которую вы не заметили, - это headers, передаваемая в запрос POST, иногда сайт использует идентификаторы ихэши для управления доступом к их API, в этом случае я нашел два значения, которые, как представляется, необходимы, X-CSRF-Token и X-NewRelic-ID. К счастью для нас, эти два значения доступны на странице поиска.

Вот рабочий паук, результат поиска доступен по методу self.parse_search.

import json
import scrapy

class BusForSpider(scrapy.Spider):
    name = 'busfor'
    start_urls = ['https://busfor.pl/autobusy/Sopot/Gda%C5%84sk?from_id=62113&on=2019-10-09&passengers=1&search=true&to_id=3559']
    search_url = 'https://busfor.pl/api/v1/searches'

    def parse(self, response):
        payload = {"from_id" : '62113',
                   "to_id" : '3559',
                   "on" : '2019-10-10',
                   "passengers" : 1,
                   "details" : []}
        csrf_token = response.xpath('//meta[@name="csrf-token"]/@content').get()
        newrelic_id = response.xpath('//script/text()').re_first(r'xpid:"(.*?)"')
        headers = {
            'X-CSRF-Token': csrf_token,
            'X-NewRelic-ID': newrelic_id,
            'Content-Type': 'application/json; charset=UTF-8',
        }
        yield scrapy.Request(self.search_url, callback=self.parse_search, method="POST", body=json.dumps(payload), headers=headers)

    def parse_search(self, response):
        data = json.loads(response.text)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...