Способ отправки 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)