测试大本营

python爬虫-简书点赞

2019-05-07  本文已影响351人  nayli

这些年走过最深的坑,就是工具的坑~
开始这篇文章前,很感谢这个简书网友你就像只铁甲小宝
感谢有她,指导我出坑!(源码也来自她~Thanks♪(・ω・)ノ)
————————————————————————————————————————————写在前面


1、入坑
我用的JetBrains PyCharm 4.5.2,指定2.7的python编辑器
涉及到编码语言问题以及format用法,以及其他不知名问题,执行一直报各种各样错误。。。
然后,我......最终放弃了挣扎,选择了python 3,从此条条大路通罗马~
2、再入坑
简书设置了防御机制,我是有想到这个的,但是由于自己才识学浅,仅仅是想到而已,庆幸你就像只铁甲小宝提醒了我,然后了解了一下CSRF防御。。。
既然讲到这了,顺便科普一下:(此处引用)

CSRF
跨站请求伪造(CSRF)攻击:

用户每次点击一个链接、提交一个表单,其本质就是对服务端发起一次请求。而CSRF攻击的原理就是:攻击者诱导用户点击一个链接,用户在不知情的情况下提交了一次表单请求。而表单的内容则是攻击者事先准备好的。

①用户X某,登录了论坛A,同时也打开了一个危险网站B(同一个浏览器中);
②网站B上有一个链接,该链接的实质内容是针对论坛A的一个发帖请求(比如广告贴)。
③X某处于好奇点击了该链接,造成的结果就是:X某在完全不知情的情况下在论坛A成功发表了一篇帖子。

image.png

备注: 以上攻击成功实施的关键在于,X某已经登录论坛A,并且点击跳转后的浏览器子窗体是可以访问父窗体的session id的。
假如X某复制该链接,然后手动打开一个新的浏览器粘贴访问该链接,则会提示用户处于非登录状态,该发帖请求会被拒绝。原因是新打开的浏览器无法获取前一个浏览器中的session id,服务端会将该请求当成一个新的会话,需要重新登录后才能成功执行发帖请求。

CRSF攻击防御

既然大家都了解CRSF攻击,自然有相应的防御措施,其中比较常用的就是采用token验证。
工作机制就是:用户在发送表单时还需要携带一个token值。该token一般是填写表单页中的一个隐藏字段,每次访问都不同。通过该token的验证,服务端就能知道用户的表单请求是否从表单填写页面跳转而来了。
简单举例:

①当X某主动发帖时,必定要先点击发帖编辑页面A,当填写完帖子内容后再点击【发帖】按钮。此时会将X某填写的表单内容连带页面A中隐藏的一个token发送给服务端。服务端验证token通过后才表示发帖成功。
②当危险网站诱导X某点击危险链接时,由于该链接实质就是一个发帖的post请求,跳过了访问发帖编辑页面A的过程,自然也就无法获取有效token,最终服务端会认为该发帖请求不合法。

简单来说,服务端每次通过请求数据中的token来验证表单请求是否由用户主动发送的,从而有效防御了CRSF攻击。

token认证
token作用

此处引用)

  1. Token 完全由应用管理,所以它可以避开同源策略
  2. Token 可以避免 CSRF 攻击
  3. Token 可以是无状态的,可以在多个服务间共享

Token 是在服务端产生的。如果前端使用用户名/密码向服务端请求认证,服务端认证成功,那么在服务端会返回 Token 给前端。前端可以在每次请求的时候带上 Token 证明自己的合法地位。如果这个 Token 在服务端持久化(比如存入数据库),那它就是一个永久的身份令牌。

时序图

使用 Token 和 Refresh Token 的时序图如下:


image.png
image.png
image.png

Token 都是有状态的,即在服务端需要保存并记录相关属性。

无状态token

在前端可控的情况下(比如前端和服务端在同一个项目组内),可以协商:前端一但注销成功,就丢掉本地保存(比如保存在内存、LocalStorage 等)的 Token 和 Refresh Token。基于这样的约定,服务器就可以假设收到的 Token 一定是没注销的(因为注销之后前端就不会再使用了)。
如果前端不可控的情况,仍然可以进行上面的假设,但是这种情况下,需要尽量缩短 Token 的有效期,而且必须在用户主动注销的情况下让 Refresh Token 无效。这个操作存在一定的安全漏洞,因为用户会认为已经注销了,实际上在较短的一段时间内并没有注销。如果应用设计中,这点漏洞并不会造成什么损失,那采用这种策略就是可行的。
在使用无状态 Token 的时候,有两点需要注意:

分离认证服务

当 Token 无状态之后,单点登录就变得容易了。前端拿到一个有效的 Token,它就可以在任何同一体系的服务上认证通过——只要它们使用同样的密钥和算法来认证 Token 的有效性。


image.png

如果 Token 过期了,前端仍然需要去认证服务更新 Token:


image.png
唠唠叨叨介绍就到这里了,具体的网上文章一大堆,想要具体了解,请自行百度~
3、python导入模块(当前系统环境存在多版本python)

①运行cmd
②验证当前版本(根据设置运行的名称)

#  python2.7   查看2.7版本
#  python3.7   查看3.7版本

③指定安装(请勿在python编辑器下进行下述命令,且系统环境变量已配置)

#  python3.7 -m pip install requests

4、源码

# -*- coding: utf-8 -*-
import requests
from lxml import etree
from time import time,ctime

headers = {
    # 用自己的账号的header
    #控制台查看呀,o( ̄ヘ ̄o#)
}

def fetch_url(url, page):
    data = {'page': page}
    r = requests.post(url, headers=headers, data=data)
    r.encoding = 'utf-8'
    return r.content

# 解析出来的文章url,加入到队列中
def parse(url, pages):
    article_urllist = []
    article_xpath = "//li/div[@class='content']/a[@class='title']"
    for page_number in range(1, pages + 1):
        try:
            page = fetch_url(url, page_number)
            html = etree.HTML(page)
            article_list = html.xpath(article_xpath)
            for article in article_list:
                article_urllist.append("https://www.jianshu.com" + f"{article.get('href')}")
        except:
            print('失败')
    return article_urllist

# 请求网站,点赞
def dianzan(article_url):
    try:
        a = requests.get(article_url, headers=headers)
    except:
        print('请求文章页面失败')
    html = etree.HTML(a.content)
    dianzan_path = "//meta[@property='al:android:url']"
    url_part = html.xpath(dianzan_path)[0].get('content')
    url = 'https://www.jianshu.com'+f'{url_part[9:]}'+'/like'
    # 点赞
    try:
        requests.post(url, headers = headers)
    except:
        print('点赞失败')

def run(url, page):
    n = 0
    article_list = parse(url, page)
    for article_url in article_list:
        dianzan(article_url)
        n = n + 1
    print(f'点赞文章数量{n}')

if __name__ == '__main__':
    print(ctime())
    url = 'https://www.jianshu.com/trending_notes'
    pages = 1
    start = time()
    run(url, pages)
    end = time()
    print(f'{end - start}')

4、执行结果


image.png
image.png

5、考虑了某个方向,等有结果了,在更新一下,O(∩_∩)O哈哈~

上一篇下一篇

猜你喜欢

热点阅读