我正在实施scrapy蜘蛛来抓取包含房地产优惠的网站。该网站包含房地产经纪人的电话号码,可以通过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。
答案 0 :(得分:0)
您可以在页面来源中找到令牌:
<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