python爬虫-简书点赞
这些年走过最深的坑,就是工具的坑~
开始这篇文章前,很感谢这个简书网友你就像只铁甲小宝
感谢有她,指导我出坑!(源码也来自她~Thanks♪(・ω・)ノ)
————————————————————————————————————————————写在前面
1、入坑
我用的JetBrains PyCharm 4.5.2,指定2.7的python编辑器
涉及到编码语言问题以及format用法,以及其他不知名问题,执行一直报各种各样错误。。。
然后,我......最终放弃了挣扎,选择了python 3,从此条条大路通罗马~
2、再入坑
简书设置了防御机制,我是有想到这个的,但是由于自己才识学浅,仅仅是想到而已,庆幸你就像只铁甲小宝提醒了我,然后了解了一下CSRF防御。。。
既然讲到这了,顺便科普一下:(此处引用)
CSRF
跨站请求伪造(CSRF)攻击:
用户每次点击一个链接、提交一个表单,其本质就是对服务端发起一次请求。而CSRF攻击的原理就是:攻击者诱导用户点击一个链接,用户在不知情的情况下提交了一次表单请求。而表单的内容则是攻击者事先准备好的。
image.png①用户X某,登录了论坛A,同时也打开了一个危险网站B(同一个浏览器中);
②网站B上有一个链接,该链接的实质内容是针对论坛A的一个发帖请求(比如广告贴)。
③X某处于好奇点击了该链接,造成的结果就是:X某在完全不知情的情况下在论坛A成功发表了一篇帖子。
备注: 以上攻击成功实施的关键在于,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作用
(此处引用)
- Token 完全由应用管理,所以它可以避开同源策略
- Token 可以避免 CSRF 攻击
- 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 的时候,有两点需要注意:
- Refresh 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哈哈~