Python实现北邮人BT模拟登录

如果问大家离开北邮最不舍的东西是什么?很多人肯定会脱口而出:北邮人BT!显然,北邮人BT已经融为每个BYR生活的一部分了。那么就从这个网站下手,练一练Python的爬虫吧。

很早之前写这篇文章时,对下载北邮人BT的资源的理解是先通过模拟北邮人BT登录,然后用代码下载资源。现在觉得这么做太复杂了,所以这篇文章就改成用python模拟登录北邮人BT的教程吧。

head.jpg

教程所需环境

下面是本文核心的运行环境,没有在其他环境下运行和测试,推荐大家和我采用相同的环境。

  1. Python 3.x
  2. 支持ipv6的服务器,本文使用Digital Ocean

大家可能和我一样在购买Digital Ocean之后想着如何让它发挥出更大的作用,我发现Digital Ocean支持ipv6,因此,我就想到能不能让它作为ipv4和ipv6的中转站,实现很多有意思的事情,于是就萌发了在校外下载北邮人BT资源的想法。

采用本教程的方法能够实现在校外的无ipv6的环境访问和下载北邮人BT资源到你的电脑,刷BT分享率,简直不要再赞。

更多关于选择Digital Ocean的理由可以见文末。

前期配置

在购买DO服务器之后,会获得v4和v6两个地址,这两个地址都能访问DO。如果你没有ipv6的地址,但是你可以通过ipv4连接到DO服务器,然后让服务器通过ipv6访问和下载BT资源,资源先下载到服务器上,最后通过ipv4传到你的电脑上。这就是本文的思路。

在购买服务器完成之后,建议大家配置shadowsocks,这真是个好东西,不仅可以实现科学上网,还可以让你在v4的环境下访问v6的网页,效果可以看下图:

在ipv4环境下访问北邮人BT网页

上图是在我把shadowsocks设置为全局模式时,能够使用浏览器访问北邮人BT,但系统没有ipv6地址,所以命令行可以连接到北邮人论坛却无法连接到北邮人BT。

这样做可以让你挑选北邮人BT的资源,但是因为没有ipv6的环境,所以不能方便地通过uTorrent等客户端下载资源。我们的做法是在自己电脑上使用shadowsocks代理访问北邮人BT挑选资源,得到想要下载的资源的id,然后在服务器上运行python脚本下载该id对应的资源,再通过ssh或者ftp传到本地电脑。

登录分析

前文已经分析了,必须实现在DO服务器上能模拟登录北邮人BT,才能下载资源。故我们首先实现模拟登录BT。

网站模拟登录的分析过程可以参考之前的模拟登录北邮人论坛的文章,这里简单分析BT的模拟登录过程。

在浏览器上打开北邮人BT,退出登录,即在http://bt.byr.cn/login.php 界面,按F12打开开发者选项,选择Network选项卡,勾上Preserve log选项。

登录前的状态

然后填写用户名密码、验证码,点击登录,如果填写的正确就能跳转到BT主界面。

选项卡记录的登录参数

从上面的截图能看出来,在登录BT的时候向http://bt.byr.cn/takelogin.php通过POST方式发送了4个参数,包括用户名,密码,验证码,还有验证码图片的hash。前面的三个参数都是自己填写的,但是验证码的hash从哪里找出来呢?难道自己计算吗?

还好,通过在源代码中搜索imagehash,可以发现出现了两次,一次是图片的链接,一次是一个隐藏的输入框,输入框里包含着正确的iamgehash。如下图:

找出imagehash

综上分析,我们已经可以把登录要提交的所有信息全部分析出来了,可以在源代码中使用正则表达式等工具提取出imagehash,但验证码要怎么处理呢?

验证码处理

前面虽然找出了验证码图片的hash,但是没法找出验证码图片对应的字符串(能找出的话验证码也没存在的意义了)。我们可以推测,当我们提交验证码字符串的时候,服务器会进行输入的验证码字符串和验证码图片hash的验证,如果匹配说明验证码正确。下面我们要解决验证码的问题。

处理验证码一般有几个思路:

  1. 手动填写
  2. 机器学习模型处理
  3. 第三方服务

这里为了方便,直接使用手动填写方式即可。思路是这样的,先用Python请求到登录页的网址,然后把验证码图片保存下来,再然后直接打开图片查看,把验证码填写即可。

如果你在自己电脑上模拟登录可以很简单的用图片查看器打开图片,但是如果在服务器上运行脚本的话该怎么办呢?我这里提供几个思路。

  1. catimg在命令行中显示图片(不清晰)
  2. 把图片下载到本地查看(麻烦)
  3. 把图片转成字符画在命令行显示(代码量大)

我用的比较高逼格的第三种方式,效果如下:

验证码转字符画

能在终端中查看到验证码图片的话就能手动输入了~至此模拟登录要找到各个参数已经完全找到了。

保存cookies

我们没有必要每次访问bt都去模拟登录,这样很麻烦。为了方便我们可以把cookies保存,以后使用cookies自动登录即可。

完整代码

下面是完整的代码,将代码保存成.py文件再传到DO服务器,用Python命令运行。

运行之后,当前目录下会生成check_code.jpg,imgtochar.txt,cookies.txt等文件。请不要删除cookies.txt文件,这是以后登录使用的cookies。程序运行时会自动监测当前文件夹下是否存在cookies.txt,如果不存在会执行手动输入用户名密码验证码的登录操作,否则会直接使用cookies登录。

密码输入采用不显示的方式,不用担心密码没输上去。这是在服务器上运行程序的结果,注意,第一次需要输入用户名密码验证码,第二次登录直接使用cookies登录、不用再次输入。

服务器上两次模拟登录
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
# coding=utf-8
import os
import re
import pickle
import requests
import requests.utils
from PIL import Image
imgpath = 'check_code.jpg'
ascii_char = list(r"$@&%B#... ")
def select_ascii_char(r, g, b):
gray = int((19595 * r + 38469 * g + 7472 * b) >> 16) # ‘RGB-灰度值’转换公式
unit = 256.0 / len(ascii_char) # ascii_char中的一个字符所能表示的灰度值区间
return ascii_char[int(gray / unit)]
# 返回给定路径图片的字符表示,用户在此还可以指定输出字符画的宽度和高度
def output(imgpath, width=150, height=100):
im = Image.open(imgpath)
im = im.resize((width, height), Image.NEAREST)
# 裁剪
box = (0, 30, width, 70)
# 这里的参数可以这么认为:从某图的(x,y)坐标开始截,截到(width+x,height+y)坐标
# 所包围的图像,crop方法与php中的imagecopy方法大为不一样
newIm = im.crop(box)
txt = ""
for h in range(newIm.size[1]):
for w in range(newIm.size[0]):
txt += select_ascii_char(*newIm.getpixel((w, h))[:3]) # 此处请看详解(1)
txt += '\n'
return txt
def save_as_txtfile(txt):
with open('imgtochar.txt', 'w') as f:
f.write(txt)
def codeBegin():
print(output(imgpath))
save_as_txtfile(output(imgpath))
def getCheckCode(image_get_url):
im = requests.get(image_get_url) # 获取验证码和cookies值
with open('check_code.jpg', 'wb') as f:
f.write(im.content)
# img = Image.open('check_code.jpg')
# img.show()
codeBegin()
check_code = input("code:")
print("your input:" + check_code)
return check_code
def login():
files = os.listdir('.')
if 'cookies.txt' in files:
with open('cookies.txt', 'rb') as f:
cookies = requests.utils.cookiejar_from_dict(pickle.load(f))
bt_session = requests.session()
bt_session.cookies = cookies
try:
torrent_url = 'http://bt.byr.cn/torrents.php'
test = bt_session.get(torrent_url)
if test.status_code != 200 or test.url != torrent_url:
print('Something wrong when login in. Delete the cookies and relogin plese.\n')
return
except:
print("net error")
return
else:
username = input("your username:")
password = input("your password:")
login_php = 'http://bt.byr.cn/login.php'
try:
bt_session = requests.Session()
req = bt_session.get(login_php)
except:
print("net error")
return
print(req.text)
# <input name="imagehash" value="2cb98173c9a2fc28f0976f9a5b715db5">
imageHash = re.findall('name=\"imagehash\" value=\"(.*)\"/>', req.text)[0]
print(imageHash)
image_get_url = 'http://bt.byr.cn/image.php?action=regimage&imagehash=' + imageHash
check_code = getCheckCode(image_get_url)
login_post_url = 'http://bt.byr.cn/takelogin.php'
login_datas = {
'username': username,
'password': password,
'imagestring': check_code,
'imagehash': imageHash
}
try:
main_page = bt_session.post(login_post_url, login_datas)
print(main_page.text)
if main_page.url != "http://bt.byr.cn/index.php":
print("login error")
return
with open('cookies.txt', 'wb') as f:
pickle.dump(requests.utils.dict_from_cookiejar(bt_session.cookies), f)
except:
print("net error")
return bt_session
session = login()

郑重声明:本系列文章提供的是在无ipv6环境下访问北邮人BT并且下载资源的一种方式,重在技术探讨,严禁使用本教程方法传播销售BT资源,否则造成的后果自负。在未获得作者本人许可之前不得将本文转载,转载请联系fuxuemingzhu#163.com(将#换成@)。

走心推广

因为本博客部署在Digital Ocean 服务器上,每个月都要有5美元的成本,对于学生党来说也是不小开支。所以既然你能看到这篇博客的话,希望你能帮助我一下,鼓励我写出更好的文章。

Digital Ocean 服务器购买

如果你也需要购买服务器,强烈推荐Digital Ocean,推荐原因如下:

  • 基础套餐很便宜,每月最低5美元
  • 服务器资源很给力,基础套餐配置是512MB内存,20GB的SSD硬盘,带宽不限制
  • 可以搭建ShadowSocks,实现科学上网(特别实用!!)
  • 支持ipv6,轻松解决校园网流量不够用的问题

我使用的是san francisco节点,搭建好ss之后,看油管1080p视频轻松无压力!!

你如果使用我的这个网址注册Digital Ocean,你可以得到10美元的代金券,我也能赚到一点,就是这个链接:https://m.do.co/c/86d4e56f6c7a

另外,如果你也是学生,有校园网邮箱,即可申请GitHub的Student Pack,免费送你50美刀的Digital Ocean代金券!地址是:https://education.github.com/pack/offers

菜菜手绘坊

菜菜手绘坊是我的姐姐在经营的一个手绘店铺,每一笔都是我的姐姐亲自画出来的。手绘坊里有很多风格可以选择,特别适合做头像,屏保,聊天背景等等!!甚至可以画好图之后做成手机壳,情侣T恤都是可以的!价格真的很便宜,可以加微信具体聊价格,绝对会让你惊喜!

更详细的宣传可以看我的这篇文章:http://fuxuemingzhu.me/drawing/

店主微信和QQ:290885604

下面是暗黑风格的,看看有没有心动:

暗黑风格:
暗黑

如果满分10分,你会给这篇文章打几分?
负雪明烛 微信

微信

负雪明烛 支付宝

支付宝