网络爬虫---对于scrapy框架中的Request()、FormRequest()、FormRequest.from_response()做一个小结

版权声明:https://blog.csdn.net/qq_43546676 https://blog.csdn.net/qq_43546676/article/details/89043445

一、Request()类的实例化

对于爬取普通网站,不需要验证码,不需要登入的界面,我们一般用scrapy.Request类直接去爬取信息就行,下面是Request类的定义:

class Request(object_ref):

    def __init__(self, url, callback=None, method='GET', headers=None, body=None,
                 cookies=None, meta=None, encoding='utf-8', priority=0,
                 dont_filter=False, errback=None, flags=None):
                 # url是要爬取的网址
                 # callback是回调函数
                 # method是请求的方式post还是get
                 # headers是浏览器伪装的头信息
                 # body是网页源代码信息
                 # cookies是登入某网站后,网站在你电脑上保留的信息
                 # meta要携带或者传递的信息
                 # encoding是编码方式
                 # priority用来设置访问网站的优先级
                 # dont_filter是否允许重复爬取网站

可以看见,其中url,即要爬取的目标网站是必填的,其他的是选填的,method=‘GET’,说明此类是get请求,实例化该对象后,会得到一个response。
eg:

def start_requests(self):
        # 首先爬一次登陆页,看是否有验证码。回调函数为parse(),'cookiejar'的值为1表示开启状态
        # 这里要返回一个可迭代对象,用yield本身就是可迭代对象,但是,这里是return,所以用[]将其构造成一个可迭代对象
        return [Request("https://accounts.douban.com/passport/login", meta={'cookiejar': 1}, headers=self.header, callback=self.parse)]

二、scrapy.FormRequest与scrapy.http.FormRequest

(1)普通请求使用scrapy.Request类就可以实现,但是遇到模拟表单或Ajax提交post请求的时候,Request类就不如 子类 FormRequest类方便了,因为他自带 formdata ,专门用来设置表单字段数据,即填写账号、密码,实现登入,默认method也是POST。
(2)FormRequest相当于是手动指定post。
(3)事实上,scrapy.FormRequest()与scrapy.http.FormRequest()使用起来的区别不大,你可以将两种方法等价互换。
eg:

def start_requests(self):
    form_data = {'f1':'1', 'f2':'100'}  # 表单数据,字典格式,注意数字也要用引号引起来,否则报错。
    yield scrapy.FormRequest(url, formdata=form_data) # 还可以通过callback修改回调函数等
# 也可以
def start_requests(self):
    form_data = {'f1':'1', 'f2':'100'}  # 表单数据,字典格式,注意数字也要用引号引起来,否则报错。
    yield scrapy.http.FormRequest(url, formdata=form_data) # 还可以通过callback修改回调函数等

三、FormRequest.from_response()

(1)FormRequest.from_response也可以进行设置 formdata,用来填写并提交表单,实现模拟登入。
(2)FormRequest.from_response相当于是自动识别post。
(3)FormRequest.from_response与FormRequest.http.from_response也没有区别。
eg:

def parse(self, response):
        return scrapy.FormRequest.from_response(
            response,
            formdata={'username': 'john', 'password': 'secret'},
            callback=self.after_login
        )

三、scrapy.FormRequest与FormRequest.from_response 的区别##

1.什么情况下分别使用什么

先找到填写表单时发送的post请求的地址,下面以豆瓣登入为例子:
在这里插入图片描述
可以看见其post的地址为:https://accounts.douban.com/j/mobile/login/basic
然后用浏览器访问https://accounts.douban.com/j/mobile/login/basic
在这里插入图片描述
发现页面没有表单信息(也就是没有填写账号、密码的地方),所以,我们只能采用scrapy.FormRequest,手动的去发送post请求。
如果浏览器访问某post网址时,里面有表单信息,这时候你可以用FormRequest.from_response也可以用scrapy.FormRequest实现模拟登入

2.参数的不一样

scrapy.FormRequest的必填参数是目标网址,而FormRequest.from_response的必填参数是response
eg:

def parse(self, response):
        # 如果有验证码
        # 没有验证码,就进行登入
        # 设置要发送的post信息
        data = {
            'name': '18371417971',
            'password': 'wanghao211',
            'remember': 'false'
        }
        print("登入中...")
        return FormRequest(
            url='https://accounts.douban.com/j/mobile/login/basic',
            method='post',
            formdata=data,
            meta={'cookiejar':response.meta['cookiejar']},
            # 如果需要多次提交表单,且url一样,那么就必须加此参数dont_filter,防止被当成重复网页过滤掉了
            dont_filter=True,
            callback=self.next
        )
##############################
def parse(self, response):
        # 如果有验证码
        # 没有验证码,就进行登入
        # 设置要发送的post信息
        data = {
            'name': '18371417971',
            'password': 'wanghao211',
            'remember': 'false'
        }
        print("登入中...")
        return FormRequest(
            url=response,
            method='post',
            formdata=data,
            meta={'cookiejar':response.meta['cookiejar']},
            # 如果需要多次提交表单,且url一样,那么就必须加此参数dont_filter,防止被当成重复网页过滤掉了
            dont_filter=True,
            callback=self.next
            )

3.小结

总的来说,scrapy.FormRequest的功能更加强大,如果FormRequest.from_response 不能解决就用scrapy.FormRequest来解决模拟登入,毕竟是手动设置目标网址,比自动识别要精准。

猜你喜欢

转载自blog.csdn.net/qq_43546676/article/details/89043445
今日推荐