参考https://blog.csdn.net/qq_43546676/article/details/89043445,还有自己的总结:
一、scrapy.FormRequest:适用于以下三种情况
(1)不需要post或登录,用get方法爬去内容时候,直接用它
(2)登录,但没有登录的form(没有输入用户和口令的界面)
(3)需要post,单没有form,而是用Ajax提交post
二、FormRequest.from_response
适用于以下情况
(1)提交一个form, 有界面输入框,用来post 数据
(2)官方特别推荐的一种场景,登录界面,登录画面进入(get)和提交账号口令(post) 是同一个url的情况。
<form action="/login" method="post" accept-charset="utf-8" > <input type="hidden" name="csrf_token" value="zrfpdvAFSoVQGYHsLRtBgXKZuDENhbqwOkCmMnTeIWJUlxaijycP"/> <div class="row"> <div class="form-group col-xs-3"> <label for="username">Username</label> <input type="text" class="form-control" id="username" name="username" /> </div> </div> <div class="row"> <div class="form-group col-xs-3"> <label for="username">Password</label> <input type="password" class="form-control" id="password" name="password" /> </div> </div> <input type="submit" value="Login" class="btn btn-primary" /> </form>
如上面例子,一些登录界面,除了肉眼可看到的输入 用户名,密码 ,系统还隐藏着其他内容,作为csrf防攻击策略。作为爬虫,模拟登录时候要和input hidden 数据一起提交。
(1)如果用scrapy.FormRequest, 则需要提前爬取csrf_token的值,然后,csrf_token+用户+口令一起提交。比较麻烦
(2)FormRequest.from_response,则可以无视csrf_token,from_response会自动取得csrf_token,并且和用户口令提起提交。
看官网的解释:
It is usual for web sites to provide pre-populated form fields through <input type="hidden"> elements,
such as session related data or authentication tokens (for login pages). When scraping,
you’ll want these fields to be automatically pre-populated and only override a couple of them, such as the user name and password.
You can use the FormRequest.from_response() method for this job
简单翻译,使用FormRequest.from_response()会让hidden项目自动赋值,你只需要填充用户名和密码,就可以提交。
当然,一些网站,比如github, 他的login 进入页面(get)和提交(post)页面不同
github
self.login_url = 'https://github.com/login'
self.post_url = 'https://github.com/session'