Scrapy模拟登录之发送POST请求

鳄鱼君Ba

发表文章数:518

Vieu四代商业主题

高扩展、安全、稳定、响应式布局多功能模板。

¥69 现在购买
首页 » Python教程 » Scrapy模拟登录之发送POST请求

使用scrapy.Request的时候一直都是发送的get请求,那么post请求就需要使用scrapy.FormRequest来发送,同时使用formdata来携带需要post请求的数据。

这里以github网站作为演示,使用POST请求登录。首先需要分析网页,我们发现:https://github.com/login是登录页面,我们在这页面尝试等登录,寻找POST提交的url地址。第一次登陆输错密码,看看结果:

Scrapy模拟登录之发送POST请求

再输入错误密码之后,跳到了:https://github.com/session,我们查看具体的参数信息,其中参数authenticity_tokencommit比较特别,我么可以在https://github.com/login进行寻找,发现正好存在:

Scrapy模拟登录之发送POST请求

这是一种固定的套路,不在参数不在前一个页面,就可能在后一个页面中。那么我么可以把:https://github.com/login作为起始的url,提取我们想要的参数,然后通过

# -*- coding: utf-8 -*-
import scrapy,re

class GithubSpider(scrapy.Spider):
    name = 'github'
    allowed_domains = ['github.com']
    start_urls = ['http://github.com/login']

    def parse(self, response):
        #在http://github.com/login提取参数
        authenticity_token=response.xpath('//input[@name="authenticity_token"]/@value').extract_first()
        commit=response.xpath('//input[@name="commit"]/@value').extract_first()
        #构造一个字典
        post_data={
            'login':'鳄鱼大师',
            'password':'12345678',
            'authenticity_token':authenticity_token,
            'commit':commit
        }
        #找到url发送POST请求,after_login处理之后的响应
        yield scrapy.FormRequest(
            'https://github.com/session',
            callback=self.after_login,
            formdata=post_data
        )
    def after_login(self,response):
        name=re.findall('鳄鱼大师',response.body.decode(),re.S)
        print(name)

POST提交所需要的参数很多,我们先测试看着比较重要的参数,如果不成功,可携带所有的参数。那么上面的代码,是成功提取到鳄鱼大师这个字符串,但其实密码是错误的,这个鳄鱼大师是网页自动保存的username,不是我们登录之后获取到的。这你可能遇到过一些错误:

  • twisted.web._newclient.ResponseNeverReceived: []—原因是没有合适的请求头,添加即可
  • Connection to the other side was lost in a non-clean fashion :记得url需要正确,是https就不要写http,可以到浏览器复制。
  • RuntimeWarning: Could not load referrer policy ‘origin-when-cross-origin, strict-origin-when-cross-origin’提示WARNING警告,这关乎referrer策略问题,对代码的运行没有发现影响,只是现实警告信息。

那么我么在参数中添加正确的用户名和密码,来测试是否登录成功。我们可以把响应的html写入到本地文件中去,在浏览器中可以清除的看到是否成功。需要注意的是,第一次登陆会让输入安全码,就是手机验证码,我们需要完成这一步,然后在进行尝试,代码参考:

# -*- coding: utf-8 -*-
import scrapy,re

class GithubSpider(scrapy.Spider):
    name = 'github'
    allowed_domains = ['github.com']
    start_urls = ['https://github.com/login']

    def parse(self, response):
        #在http://github.com/login提取参数
        authenticity_token=response.xpath('//input[@name="authenticity_token"]/@value').extract_first()
        commit=response.xpath('//input[@name="commit"]/@value').extract_first()
        #构造一个字典
        post_data={
            'login':'正确的用户名',
            'password':'正确的密码',
            'authenticity_token':authenticity_token,
            'commit':commit,
        }
        print(post_data)
        #找到url发送POST请求,after_login处理之后的响应
        yield scrapy.FormRequest(
            'https://github.com/session',
            callback=self.after_login,
            formdata=post_data
        )
    def after_login(self,response):
        #保存到本地,我们就不需要在提取相关数据了
        with open('html.html','wb') as f:
            f.write(response.body)
        

可能有的同学有疑问,表单提交的页面是https://github.com/session,怎么找到的呢?通常我们的POST请求在网页中都是用的是form标签,我们再看一下这个:https://github.com/login的html:

Scrapy模拟登录之发送POST请求

我们可以看到,在form表单中是存在https://github.com/session的url。scrapy.FormRequest提供了from_response方法,可以自动从相应中找到form表单进行登录,代码参考:

# -*- coding: utf-8 -*-
import scrapy


class Github2Spider(scrapy.Spider):
    name = 'github2'
    allowed_domains = ['github.com']
    start_urls = ['https://github.com/login']

    def parse(self, response):
        yield scrapy.FormRequest.from_response(
            response,#自动从response中寻找form表单
            formdata={'login':'1552797557@qq.com','password':'1897745389dsgmmc',},
            callback=self.after_login
        )
    def after_login(self,response):
        with open('html.html', 'wb') as f:
            f.write(response.body)

这种方式少写很多代码,但是如果一个网页存在多个form表单的话,该怎么办?我们查看源码发现:

def from_response(cls, response, formname=None, formid=None, formnumber=0, formdata=None,clickdata=None, dont_click=False, formxpath=None, formcss=None, **kwargs):
    .......
    .......

form表单是可以进行XPATH定位的,这个方法也是比较灵活的,具体自己尝试。

未经允许不得转载:作者:鳄鱼君Ba, 转载或复制请以 超链接形式 并注明出处 鳄鱼君Ba
原文地址:《Scrapy模拟登录之发送POST请求》 发布于2020-03-17

分享到:
赞(2) 赏杯咖啡

文章对你有帮助可赏作者一杯咖啡

支付宝扫一扫打赏

微信扫一扫打赏

Vieu4.6主题
专业打造轻量级个人企业风格博客主题!专注于前端开发,全站响应式布局自适应模板。
切换注册

登录

忘记密码 ?

您也可以使用第三方帐号快捷登录

Q Q 登 录
微 博 登 录
切换登录

注册