前言
本文中如有错误,望指正。
背景
最近在爬取某网站时发现之前学习中没有遇到过的情况,虽然都是发送post请求,但是原来的表单数据Form data变为了request payload(如图)。仍然使用了原来的FormRequest方法,但是不管用。
理论学习
目前常见的HTTP请求中主要的方式为GET和POST方式。
- GET请求
GET请求时,参数主要放在url里面,形式主要为key1=value1&key2=value2形式,参数以“&”连接。比如在百度中查询某一内容,链接为:
2.POST请求
2.1 Form data
对于POST请求中常见的Form data,表单参数是在请求体中,也是以key-value的形式存在于请求体中。此时的POST请求中的 Content-Type为application/x-www-form-urlencoded(默认的)
2.2 request payload
如果使用原生 AJAX POST请求,请求表单的参数在request payload中。此时的POST请求中的 Content-Type为application/json。
关于Content-Type的解释,请参考博客http://www.cnblogs.com/tugenhua0707/p/8975121.html。(自己在查找资料的时候发现的)。
2.3区别(上面的可能因为我写的不详细而不明白我在说什么,但请记住下面的)
如果一个请求的Content-Type设置为application/x-www-form-urlencoded, 那么这个POST请求会被认为是 post 表单请求,此时可以使用我们熟悉的Scrapy.FormRequest
发送请求以访问页面。
其他形式的POST请求是放在request payload中(现在一般使用json格式),请求的Content-Type设置为application/json。此时,我们可以将要传送的数据放在Scrapy.Request
的body中,然后设置请求头部的Content-Type为application/json。
码上行动
以网站http://www.yuecai.com/purchase/?SiteID=21为例,网站首页是这样的:
当我们翻页时会发现加载的网页中有一个叫search的页面,向其发送一个post请求则会返回一个json格式的数据。具体如图示:
翻页时,发送post请求,且数据以request payload形式发送。返回的数据如下图:
返回的数据正是我们想要爬取的数据。
现在我们用postman来向这个网站发送请求。如前面理论部分所说,Content-Type设置为application/json,传送的参数以json放入body中。点击发送后我们可以看到返回的数据 。
返回数据成功。
代码:
def start_requests(self):
true_url = 'http://iris.yuecai.com/iris/v1/purchase/search'
data = {'page':'1','size':'20','teseData':'2','sort':None,'word':None,'zone':None}
yield scrapy.Request(url=true_url,method='POST',body=json.dumps(data),callback=self.parse)
def parse(self, response):
f = open('payload.txt','w',encoding='utf-8')
f.write(response.text)
f.close()
将返回的response写入文本中,并打开: