zoukankan      html  css  js  c++  java
  • 模拟登录

      1 requess模块处理cookie相关的请求
      2 学习目标
      3 掌握requests处理cookie的三种方法
      4 1 爬虫中使用cookie
      5 为了能够通过爬虫获取到登录后的页面,或者是解决通过cookie的反扒,需要使用request来处理cookie相关的请求
      6 
      7 1.1 爬虫中使用cookie的利弊
      8 带上cookie的好处
      9 
     10 能够访问登录后的页面
     11 能够实现部分反反爬
     12 带上cookie的坏处
     13 
     14 一套cookie往往对应的是一个用户的信息,请求太频繁有更大的可能性被对方识别为爬虫
     15 那么上面的问题如何解决 ?使用多个账号
     16 1.2 requests处理cookie的方法
     17 使用requests处理cookie有三种方法:
     18 
     19 cookie字符串放在headers中
     20 把cookie字典放传给请求方法的cookies参数接收
     21 使用requests提供的session模块
     22 2 cookie添加在heades中
     23 2.1 headers中cookie的位置
     24 
     25 
     26 headers中的cookie:
     27 使用分号(;)隔开
     28 分号两边的类似a=b形式的表示一条cookie
     29 a=b中,a表示键(name),b表示值(value)
     30 在headers中仅仅使用了cookie的name和value
     31 2.2 cookie的具体组成的字段
     32 
     33 
     34 由于headers中对cookie仅仅使用它的name和value,所以在代码中我们仅仅需要cookie的name和value即可
     35 
     36 2.3 在headers中使用cookie
     37 复制浏览器中的cookie到代码中使用
     38 
     39 headers = {
     40 "User-Agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36",
     41 "Cookie":" Pycharm-26c2d973=dbb9b300-2483-478f-9f5a-16ca4580177e; Hm_lvt_98b9d8c2fd6608d564bf2ac2ae642948=1512607763; Pycharm-26c2d974=f645329f-338e-486c-82c2-29e2a0205c74; _xsrf=2|d1a3d8ea|c5b07851cbce048bd5453846445de19d|1522379036"}
     42 
     43 requests.get(url,headers=headers)
     44 注意:
     45 cookie有过期时间 ,所以直接复制浏览器中的cookie可能意味着下一程序继续运行的时候需要替换代码中的cookie,对应的我们也可以通过一个程序专门来获取cookie供其他程序使用;当然也有很多网站的cookie过期时间很长,这种情况下,直接复制cookie来使用更加简单
     46 
     47 3 使用cookies参数接收字典形式的cookie
     48 cookies的形式:字典
     49 cookies = {"cookie的name":"cookie的value"}
     50 使用方法:
     51 requests.get(url,headers=headers,cookies=cookie_dict}
     52 4 使用requests.session处理cookie
     53 前面使用手动的方式使用cookie,那么有没有更好的方法在requets中处理cookie呢?
     54 
     55 requests 提供了一个叫做session类,来实现客户端和服务端的会话保持
     56 
     57 会话保持有两个内涵:
     58 
     59 保存cookie,下一次请求会带上前一次的cookie
     60 实现和服务端的长连接,加快请求速度
     61 4.1 使用方法
     62 session = requests.session()
     63 response = session.get(url,headers)
     64 session实例在请求了一个网站后,对方服务器设置在本地的cookie会保存在session中,下一次再使用session请求对方服务器的时候,会带上前一次的cookie
     65 
     66 4.2 动手练习:
     67 动手尝试使用session来登录人人网: http://www.renren.com/PLogin.do (先不考虑这个url地址从何而来),请求体的格式:{"email":"username", "password":"password"}
     68 
     69 思路分析
     70 准备url地址和请求参数
     71 构造session发送post请求
     72 使用session请求个人主页,观察是否请求成功
     73 5 小结
     74 cookie字符串可以放在headers字典中,键为Cookie,值为cookie字符串
     75 可以把cookie字符串转化为字典,使用请求方法的cookies参数接收
     76 使用requests提供的session模块,能够自动实现cookie的处理,包括请求的时候携带cookie,获取响应的时候保存cookie
     77 
     78 
     79 
     80 
     81 
     82 
     83 scrapy模拟登陆
     84 
     85 应用 scrapy直接携带cookie模拟登陆的方法
     86 应用 scrapy.FormRequest()发送post请求进行登陆
     87 应用 scrapy.FormRequest.from_response()发送表单请求
     88 1 模拟登陆的方法
     89 1.1 requests模块是如何实现模拟登陆的?
     90 直接携带cookies请求页面
     91 找url地址,发送post请求存储cookie
     92 1.2 selenium是如何模拟登陆的?
     93 找到对应的input标签,输入文本点击登陆
     94 1.3 scrapy有三种方法模拟登陆
     95 直接携带cookies
     96 找url地址,发送post请求存储cookie
     97 找到对应的form表单,自动解析input标签,自动解析post请求的url地址,自动带上数据,自动发送请求
     98 2 scrapy携带cookies直接获取需要登陆后的页面
     99 2.1 应用场景
    100 cookie过期时间很长,常见于一些不规范的网站
    101 能在cookie过期之前把所有的数据拿到
    102 配合其他程序使用,比如其使用selenium把登陆之后的cookie获取到保存到本地,scrapy发送请求之前先读取本地cookie
    103 2.2 实现:重构scrapy的starte_rquests方法
    104 scrapy中start_url是通过start_requests来进行处理的,其实现代码如下
    105 
    106 def start_requests(self):
    107     cls = self.__class__
    108     if method_is_overridden(cls, Spider, 'make_requests_from_url'):
    109         warnings.warn(
    110             "Spider.make_requests_from_url method is deprecated; it "
    111             "won't be called in future Scrapy releases. Please "
    112             "override Spider.start_requests method instead (see %s.%s)." % (
    113                 cls.__module__, cls.__name__
    114             ),
    115         )
    116         for url in self.start_urls:
    117             yield self.make_requests_from_url(url)
    118     else:
    119         for url in self.start_urls:
    120             yield Request(url, dont_filter=True)
    121 所以对应的,如果start_url地址中的url是需要登录后才能访问的url地址,则需要重写start_request方法并在其中手动添加上cookie
    122 
    123 2.3 携带cookies登陆github
    124 测试账号 noobpythoner zhoudawei123
    125 
    126 import scrapy
    127 import re
    128 
    129 class Login1Spider(scrapy.Spider):
    130     name = 'login1'
    131     allowed_domains = ['github.com']
    132     start_urls = ['https://github.com/NoobPythoner'] # 这是一个需要登陆以后才能访问的页面
    133 
    134     def start_requests(self): # 重构start_requests方法
    135         # 这个cookies_str是抓包获取的
    136         cookies_str = '...' # 抓包获取
    137         # 将cookies_str转换为cookies_dict
    138         cookies_dict = {i.split('=')[0]:i.split('=')[1] for i in cookies_str.split('; ')}
    139         yield scrapy.Request(
    140             self.start_urls[0],
    141             callback=self.parse,
    142             cookies=cookies_dict
    143         )
    144 
    145     def parse(self, response): # 通过正则表达式匹配用户名来验证是否登陆成功
    146         # 正则匹配的是github的用户名
    147         result_list = re.findall(r'noobpythoner|NoobPythoner', response.body.decode()) 
    148         print(result_list)
    149         pass
    150 注意:
    151 scrapy中cookie不能够放在headers中,在构造请求的时候有专门的cookies参数,能够接受字典形式的coookie
    152 在setting中设置ROBOTS协议、USER_AGENT
    153 3. scrapy.FormRequest发送post请求
    154 我们知道可以通过scrapy.Request()指定method、body参数来发送post请求;那么也可以使用scrapy.FormRequest()来发送post请求
    155 
    156 3.1 scrapy.FormRequest()的使用
    157 通过scrapy.FormRequest能够发送post请求,同时需要添加fromdata参数作为请求体,以及callback
    158 
    159 yield scrapy.FormRequest(
    160     "https://github.com/session",
    161     formdata={
    162         "authenticity_token":authenticity_token,
    163         "utf8":utf8,
    164         "commit":commit,
    165         "login":"noobpythoner",
    166         "password":"zhoudawei123"
    167     },
    168     callback=self.parse_login
    169 )
    170 3.2 使用scrapy.FormRequest()登陆github
    171 3.2.1 思路分析
    172 找到post的url地址:点击登录按钮进行抓包,然后定位url地址为https://github.com/session
    173 
    174 找到请求体的规律:分析post请求的请求体,其中包含的参数均在前一次的响应中
    175 
    176 否登录成功:通过请求个人主页,观察是否包含用户名
    177 
    178 3.2.2 代码实现如下:
    179 import scrapy
    180 import re
    181 
    182 class Login2Spider(scrapy.Spider):
    183    name = 'login2'
    184    allowed_domains = ['github.com']
    185    start_urls = ['https://github.com/login']
    186 
    187    def parse(self, response):
    188        authenticity_token = response.xpath("//input[@name='authenticity_token']/@value").extract_first()
    189        utf8 = response.xpath("//input[@name='utf8']/@value").extract_first()
    190        commit = response.xpath("//input[@name='commit']/@value").extract_first()
    191 
    192         #构造POST请求,传递给引擎
    193        yield scrapy.FormRequest(
    194            "https://github.com/session",
    195            formdata={
    196                "authenticity_token":authenticity_token,
    197                "utf8":utf8,
    198                "commit":commit,
    199                "login":"noobpythoner",
    200                "password":"***"
    201            },
    202            callback=self.parse_login
    203        )
    204 
    205    def parse_login(self,response):
    206        ret = re.findall(r"noobpythoner|NoobPythoner",response.text)
    207        print(ret)
    208 4. scrapy自动提交表单
    209 4.1 scrapy.Formrequest.from_response
    210 它能够自动的从响应中寻找form表单,然后把formdata中的数据提交到action对应的url地址中
    211 
    212 yield scrapy.FormRequest.from_response(
    213     response, # 传入response对象,自动解析
    214     # 可以通过xpath来定位form表单,当前页只有一个form表单时,将会自动定位
    215     formxpath='//*[@id="login"]/form',  # 可以不写
    216     formdata={'login': 'noobpythoner', 'password': '***'},
    217     callback=self.parse_login
    218 )
    219 4.2 使用scrapy.Formrequest.from_response登陆github
    220 import scrapy
    221 import re
    222 
    223 class Login3Spider(scrapy.Spider):
    224     name = 'login3'
    225     allowed_domains = ['github.com']
    226     start_urls = ['https://github.com/login']
    227 
    228     def parse(self, response):
    229         yield scrapy.FormRequest.from_response(
    230             response, # 传入response对象,自动解析
    231             # 可以通过xpath来定位form表单,当前页只有一个form表单时,将会自动定位
    232             formxpath='//*[@id="login"]/form', 
    233             formdata={'login': 'noobpythoner', 'password': 'zhoudawei123'},
    234             callback=self.parse_login
    235         )
    236 
    237     def parse_login(self,response):
    238         ret = re.findall(r"noobpythoner|NoobPythoner", response.text)
    239         print(ret)
    240 5. 小技巧
    241 在settings.py中通过设置COOKIES_DEBUG=TRUE 能够在终端看到cookie的传递传递过程 
    242 
    243 总结
    244 start_urls中的url地址是交给start_request处理的,如有必要,可以重写start_request函数
    245 直接携带cookie登陆:cookie只能传递给cookies参数接收
    246 scrapy.FormRequest()发送post请求
    247 scrapy.FormRequest.from_response()发送表单请求,接收的是response
  • 相关阅读:
    c/c++ # and ## in macros以及宏debug
    postgresql unnamed statement
    postgresql/lightdb a [left/right] join b on true的含义
    openjdk、javafx各发行版
    lightdb for postgresql PL/pgSQL perform、execute、call区别
    postgresql有mysql兼容插件吗?
    各种互联网公司,不要再那么没有分寸的刷屏QPS/TPS/日活千万这些毫无意义的数据了
    PostgreSQL分布式数据库实践
    LightDB发布日常运维管理手册
    恒生电子发布金融分布式数据库LightDB
  • 原文地址:https://www.cnblogs.com/wanglinjie/p/9337706.html
Copyright © 2011-2022 走看看