文章目录
scrapy发送post请求的三种方式:
1、携带cookie登录(Request(url,callback,cookie={})
2、使用FormRequest(url,callback,formdata={})方法发送post请求
3、使用FormRequest.from_response(url,callback,formdata)发送post请求
一、方法一:携带cookie登录(Request(url,callback,cookie={})
用法:
重写scrapy.Spider父类方法中的start_requests(self)方法,start_urls=[‘www.xxx.com’]会自动调用scrapy.Spider中的start_requests()方法对url进行访问,但是原生的start_requests()方法只能发送get请求,所以需要重写start_requests()方法用于发送post
示例代码如下:
import scrapy
import re
class YlSpider(scrapy.Spider):
name = 'yl'
# allowed_domains = ['www.xxx.com']
# 首先如果start_urls中存放的是登录后的url,直接访问是进不去的
# start_urls = ['http://www.xxx.com/']
def start_requests(self):
cookies_str = 'UM_distinctid=179f54bb6061c4-002e7dd0e97edf-f7f1939-144000-179f54bb607644; CNZZDATA1279757399=1781031899-1623318002-%7C1623318002'
# 将字符串cookie处理成字典形式
cookies = {i.split('=')[0]:i.split('=')[1] for i in cookies_str.split(';')}
# Request方法中有一个cookies参数(默认为None),该参数用于存放字典型数据(携带了cookie就相当于发送了post请求)
# 但是携带cookie的请求方式有个致命的缺陷就是cookie容易在短时间内过期,每次访问都需要获取一个cookie
yield scrapy.Request(
# 该地址为登录青年大学习之后的地址
url = "https://jxtw.h5yunban.cn/jxtw-qndxx/admin/tzbindex.php",
cookies=cookies,
callback=self.parse
)
def parse(self, response):
# 判断是否进入到了登录后的界面
print(re.findall(' 网上主题团课学习记录(实时数据)',response.body.decode()))
二、方法二:使用FormRequest(url,callback,formdata={})方法发送post请求
用法:
使用scrapy.Request的时候一直是发送的get请求,post请求需要使用scrapy.FormRequest来发送,同时使用formdata来携带需要使用的post数据
示例代码如下:
import scrapy
import re
class GithubSpider(scrapy.Spider):
name = 'github'
# allowed_domains = ['www.xxx.com']
start_urls = ['https://github.com/login'] # 该网址为不需要登录就能访问的网址
def parse(self, response):
authenticity_token = response.xpath('//input[@name="authenticity_token"]/@value').extract_first()
utf8 = response.xpath('//input[@name="utf8"]/@value').extract_first()
commit = response.xpath('//input[@name="commit"]/@value').extract_first()
# 提交post请求登录需要发送给后端的数据
post_data = dict(
login = 'username',
password = 'password',
authenticity_token = authenticity_token,
utf8 = utf8,
commit = commit,
)
yield scrapy.FormRequest(
"https://github.com/session", # 该网址为需要登录才能访问的网址
formdata = post_data,
callback=self.after_login
)
def after_login(self,response):
print(re.findall('booze|booze',response.body.decode()))
三、方法三:使用FormRequest.from_response(response,url,callback,formdata={})发送post请求
用法:
使用FormRequest.from_response()来发送,scrapy.FormRequest.from_response()这种方法就只需要传用户名(键为用户名input标签的name属性的值)和密码(键为密码input标签的name属性的值)即可,无需携带很多的formdata参数。
示例代码如下:
import scrapy
import re
class Github2Spider(scrapy.Spider):
name = 'github2'
# allowed_domains = ['github.com']
start_urls = ['http://github.com/login']
def parse(self, response):
# scrapy.FormRequest.from_response()这种方法就只需要传用户名(键为用户名input标签的name属性的值)和密码(键为密码input标签的name属性的值)即可,无需携带很多的formdata参数
yield scrapy.FormRequest.from_response(
response,# 自动的从response中寻找form表单,若没有form表单则会报raise ValueError(f"No <form> element found in {response}")
formdata={
'login':'booze',
'password':'booze',
},
callback=self.after_login
)
def after_login(self,response):
print(re.findall('booze|Booze', response.body.decode()))
注意:
- 当首次拿到cookie后,访问其他需要携带该cookie才能访问网页,不需要再次添加cookie去访问,
因为settings.py中的这两句话被注释掉了(默认是保存cookie的)
- # Disable cookies (enabled by default)
- #COOKIES_ENABLED = False(cookie在settings中默认是开启的,是的cookie能够在不同的解析函数中传递)
- 在settings.py中配置这句话可以看见cookie在不同请求中的传递的过程是什么样子的
- COOKIES_DEBUG = True
- 使用FormRequest.from_response(response,url,callback,formdata)方法的时候千万别忘了参数response
- 当页面不止一个form表单的时候可以查看FormRequest.from_response()的源码,添加参数来定位form表单