美文网首页
爬虫精进(七) ------ cookies/session

爬虫精进(七) ------ cookies/session

作者: 千喜Ya | 来源:发表于2019-07-25 21:15 被阅读0次

    博客的评论需要登录才能进行



    上图左边是“正常人”的操作:填上账号和密码;右边我们可以用工程师的思维,来分析浏览器的登录请求是怎么发送的。你需要做的是:先正常操作——填写完账号密码(别点击登录),再用工程师的做法操作:右击打开“检查”工具,点击【network】,勾选【preserve log】(持续显示请求记录,防止请求记录被刷新)。

    我们展开第0个请求【wp-login.php】,浏览一下【headers】。在【General】键里,我们可以先只看前两个参数【Request URL】(请求网址)和【Request Method】(请求方式)。


    post请求 :post和get都可以带着参数请求,不过get请求的参数会在url上显示出来。但post请求的参数就不会直接显示,而是隐藏起来。像账号密码这种私密的信息,就应该用post的请求。如果用get请求的话,账号密码全部会显示在网址上,这显然不科学!你可以这么理解,get是明文显示,post是非明文显示。通常,get请求会应用于获取网页数据,比如我们之前学的requests.get()。post请求则应用于向网页提交数据,比如提交表单类型数据(像账号密码就是网页表单的数据)。get和post是两种最常用的请求方式,除此之外,还有其他类型的请求方式,如head、options等,这里我们就不详讲了,因为一般很少用到。
    【requests headers】存储的是浏览器的请求信息,【response headers】存储的是服务器的响应信息,cookies就在其中。

    一.cookies

    当你登录博客账号spiderman,并勾选“记住我”,服务器就会生成一个cookies和spiderman这个账号绑定。接着,它把这个cookies告诉你的浏览器,让浏览器把cookies存储到你的本地电脑。当下一次,浏览器带着cookies访问博客,服务器会知道你是spiderman,你不需要再重复输入账号密码,即可直接访问。
    当然,cookies也是有时效性的,过期后就会失效。你应该有过这样的体验:哪怕勾选了“记住我”,但一段时间过去了,网站还是会提示你要重新登录,就是之前的cookies已经失效。


    headers中拉到【form data】,可以看到5个参数:



    log和pwd显然是我们的账号和密码,wp-submit猜一下就知道是登录的按钮,redirect_to后面带的链接是我们登录后会跳转到的这个页面网址,testcookie我们不知道是什么。
    怎么发表评论我们现在还不知道。那就先分析看看“正常人”发表评论,浏览器会发送什么请求。
    按“正常人”的操作写了一条“纯属测试”的评论,点击发表。
    Network里迅速加载出很多请求,点开【wp-comments-post.php】,看headers,发现我刚刚发表的评论就藏在这里。



    comment是评论内容,submit是发表评论的按钮,另外两个参数我们看不懂,不过没关系,我们知道它们都是和评论有关的参数就行。你还会发现【wp-comments-post.php】的数据并没有藏在XHR中,而是放在了Other里。原因是我们搭建网站时就写在了Other里,但常规情况下,大部分网站都会把这样的数据存储在XHR里,比如知乎的回答。

    所以评论的代码如下 :

    import requests
    #引入requests。
    url = ' https://wordpress-edu-3autumn.localprod.forc.work/wp-login.php'
    #把请求登录的网址赋值给url。
    headers = {
    'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36'
    }
    #加请求头,前面有说过加请求头是为了模拟浏览器正常的访问,避免被反爬虫。
    data = {
    'log': 'spiderman',  #写入账户
    'pwd': 'crawler334566',  #写入密码
    'wp-submit': '登录',
    'redirect_to': 'https://wordpress-edu-3autumn.localprod.forc.work/wp-admin/',
    'testcookie': '1'
    }
    #把有关登录的参数封装成字典,赋值给data。
    login_in = requests.post(url,headers=headers,data=data)
    #用requests.post发起请求,放入参数:请求登录的网址、请求头和登录参数,然后赋值给login_in。
    cookies = login_in.cookies
    #提取cookies的方法:调用requests对象(login_in)的cookies属性获得登录的cookies,并赋值给变量cookies。
    
    url_1 = 'https://wordpress-edu-3autumn.localprod.forc.work/wp-comments-post.php'
    #我们想要评论的文章网址。
    data_1 = {
    'comment': input('请输入你想要发表的评论:'),
    'submit': '发表评论',
    'comment_post_ID': '13',
    'comment_parent': '0'
    }
    #把有关评论的参数封装成字典。
    comment = requests.post(url_1,headers=headers,data=data_1,cookies=cookies)
    #用requests.post发起发表评论的请求,放入参数:文章网址、headers、评论参数、cookies参数,赋值给comment。
    #调用cookies的方法就是在post请求中传入cookies=cookies的参数。
    print(comment.status_code)
    #打印出comment的状态码,若状态码等于200,则证明我们评论成功。
    

    最后之所以加一行打印状态码的代码,是想运行整个代码后,能立马判断出评论到底有没有成功发表。只要状态码等于200,就说明服务器成功接收并响应了我们的评论请求。
    多解释一句:登录的cookies其实包含了很多名称和值,真正能帮助我们发表评论的cookies,只是取了登录cookies中某一小段值而已。所以登录的cookies和评论成功后,你在【wp-comments-post.php】里的headers面板中看到的cookies是不一致的。


    image.png

    二.session

    所谓的会话,你可以理解成我们用浏览器上网,到关闭浏览器的这一过程。session是会话过程中,服务器用来记录特定用户会话的信息。
    session和cookies的关系还非常密切——cookies中存储着session的编码信息,session中又存储了cookies的信息。
    当浏览器第一次访问购物网页时,服务器会返回set cookies的字段给浏览器,而浏览器会把cookies保存到本地。等浏览器第二次访问这个购物网页时,就会带着cookies去请求,而因为cookies里带有会话的编码信息,服务器立马就能辨认出这个用户,同时返回和这个用户相关的特定编码的session。这也是为什么你每次重新登录购物网站后,你之前在购物车放入的商品并不会消失的原因。因为你在登录时,服务器可以通过浏览器携带的cookies,找到保存了你购物车信息的session。
    优化后的发表评论的代码如下(重点看有注释的代码):

    import requests
    #引用requests。
    session = requests.session()
    #用requests.session()创建session对象,相当于创建了一个特定的会话,帮我们自动保持了cookies。
    url = 'https://wordpress-edu-3autumn.localprod.forc.work/wp-login.php'
    headers = {
    'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36'
    }
    data = {
        'log':input('请输入账号:'), #用input函数填写账号和密码,这样代码更优雅,而不是直接把账号密码填上去。
        'pwd':input('请输入密码:'),
        'wp-submit':'登录',
        'redirect_to':'https://wordpress-edu-3autumn.localprod.forc.work/wp-admin/',
        'testcookie':'1'
    }
    session.post(url,headers=headers,data=data)
    #在创建的session下用post发起登录请求,放入参数:请求登录的网址、请求头和登录参数。
    
    url_1 = 'https://wordpress-edu-3autumn.localprod.forc.work/wp-comments-post.php'
    #把我们想要评论的文章网址赋值给url_1。
    data_1 = {
    'comment': input('请输入你想要发表的评论:'),
    'submit': '发表评论',
    'comment_post_ID': '13',
    'comment_parent': '0'
    }
    #把有关评论的参数封装成字典。
    comment = session.post(url_1,headers=headers,data=data_1)
    #在创建的session下用post发起评论请求,放入参数:文章网址,请求头和评论参数,并赋值给comment。
    print(comment)
    #打印comment
    

    三.存储cookies


    把cookies存储成txt文件的代码如下(有注释的代码要认真看):

    import requests,json
    #引入requests和json模块。
    session = requests.session()   
    url = ' https://wordpress-edu-3autumn.localprod.forc.work/wp-login.php'
    headers = {
    'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36'
    }
    data = {
    'log': input('请输入你的账号:'),
    'pwd': input('请输入你的密码:'),
    'wp-submit': '登录',
    'redirect_to': 'https://wordpress-edu-3autumn.localprod.forc.work/wp-admin/',
    'testcookie': '1'
    }
    session.post(url, headers=headers, data=data)
    
    cookies_dict = requests.utils.dict_from_cookiejar(session.cookies)
    #把cookies转化成字典。
    print(cookies_dict)
    #打印cookies_dict
    cookies_str = json.dumps(cookies_dict)
    #调用json模块的dumps函数,把cookies从字典再转成字符串。
    print(cookies_str)
    #打印cookies_str
    f = open('cookies.txt', 'w')
    #创建名为cookies.txt的文件,以写入模式写入内容。
    f.write(cookies_str)
    #把已经转成字符串的cookies写入文件。
    f.close()
    #关闭文件。
    

    四.读取cookie


    读取cookies的代码如下:

    cookies_txt = open('cookies.txt', 'r')
    #以reader读取模式,打开名为cookies.txt的文件。
    cookies_dict = json.loads(cookies_txt.read())
    #调用json模块的loads函数,把字符串转成字典。
    cookies = requests.utils.cookiejar_from_dict(cookies_dict)
    #把转成字典的cookies再转成cookies本来的格式。
    session.cookies = cookies
    #获取cookies:就是调用requests对象(session)的cookies属性。
    

    cookies是否过期,我们可以通过最后的状态码是否等于200来判断。但更好的解决方法应该在代码里加一个条件判断,如果cookies过期,就重新获取新的cookies。
    更完整以及面向对象的代码应该是下面这样的:

    import requests, json
    session = requests.session()
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36'}
    
    def cookies_read():
        cookies_txt = open('cookies.txt', 'r')
        cookies_dict = json.loads(cookies_txt.read())
        cookies = requests.utils.cookiejar_from_dict(cookies_dict)
        return (cookies)
        # 以上4行代码,是cookies读取。
    
    def sign_in():
        url = ' https://wordpress-edu-3autumn.localprod.forc.work/wp-login.php'
        data = {'log': input('请输入你的账号'),
                'pwd': input('请输入你的密码'),
                'wp-submit': '登录',
                'redirect_to': 'https://wordpress-edu-3autumn.localprod.forc.work/wp-admin/',
                'testcookie': '1'}
        session.post(url, headers=headers, data=data)
        cookies_dict = requests.utils.dict_from_cookiejar(session.cookies)
        cookies_str = json.dumps(cookies_dict)
        f = open('cookies.txt', 'w')
        f.write(cookies_str)
        f.close()
        # 以上5行代码,是cookies存储。
    
    
    def write_message():
        url_2 = 'https://wordpress-edu-3autumn.localprod.forc.work/wp-comments-post.php'
        data_2 = {
            'comment': input('请输入你要发表的评论:'),
            'submit': '发表评论',
            'comment_post_ID': '13',
            'comment_parent': '0'
        }
        return (session.post(url_2, headers=headers, data=data_2))
        #以上9行代码,是发表评论。
    
    try:
        session.cookies = cookies_read()
    except FileNotFoundError:
        sign_in()
        session.cookies = cookies_read()
    
    num = write_message()
    if num.status_code == 200:
        print('成功啦!')
    else:
        sign_in()
        session.cookies = cookies_read()
        num = write_message()
    

    其实,计算机之所以需要cookies和session,是因为HTTP协议是无状态的协议。何为无状态?就是一旦浏览器和服务器之间的请求和响应完毕后,两者会立马断开连接,也就是恢复成无状态。这样会导致:服务器永远无法辨认,也记不住用户的信息,像一条只有7秒记忆的金鱼。是cookies和session的出现,才破除了web发展史上的这个难题。cookies不仅仅能实现自动登录,因为它本身携带了session的编码信息,网站还能根据cookies,记录你的浏览足迹,从而知道你的偏好,只要再加以推荐算法,就可以实现给你推送定制化的内容。

    相关文章

      网友评论

          本文标题:爬虫精进(七) ------ cookies/session

          本文链接:https://www.haomeiwen.com/subject/xhmcrctx.html