黑板客爬虫闯关第四关
来源:互联网 发布:mac os x sierra bug 编辑:程序博客网 时间:2024/04/30 18:43
上学期太忙了,第四关也就一直没去捣鼓(严重拖延症)。今天天气不错,也就抽点时间来整了整。
这一关的核心是Python多线程。密码总共有13页,每一页出现的密码是随机的。也就是说,即使你从第一页翻到最后一页,每一位的密码也不一定能全部获得。而且你会发现,页面载入速度非常慢(这是黑板课老师故意的),这样可以很好地使用Python多线程。Python的多线程和Java多线程不太一样:“Python的多线程是有compromise的,在任意时间只有一个Python解释器在解释Python bytecode”(引用自知乎-为什么有人说 Python 的多线程是鸡肋呢?)。这里的compromise是针对CPU密集型程序,但对于IO密集型程序却非常适用。因为当一个线程在等待网页数据返回时,Python解释器就可以去解释另一个线程的代码,在等待的时间内处理了其它事情。
这一关的思路很简单,先定义一个长度为100的全局list用于保存密码,初始全部置为x(这里也可以再定义一个数组用于标记对应位置密码是否已获取):
pwdlist = ['x' for i in range(0, 100)]
再定义一个全局计数器用于统计已获取密码的位数:
count = 0
当位数达到100时,则终止线程,打印密码。
每个线程都不断访问密码页面(由于每一页都是随机的,于是这里每一次访问的都是第一页),将获得的密码与已有的密码进行比较,若是新的密码(即该位为1),则将其写入pwdlist中,并置count++:
for index in range(0, len(password_pos_list)): if pwdlist[int(password_pos_list[index]) - 1] == 'x': count += 1 pwdlist[int(password_pos_list[index]) - 1] = password_val_list[index]
这里对于密码的提取用到了BeautifulSoup,登录的方法和第三关相同,具体实现这里不过多阐述。
# coding=utf-8import reimport requestsfrom bs4 import BeautifulSoupfrom threading import Threadlogin_website = 'http://www.heibanke.com/accounts/login'pwd_website = 'http://www.heibanke.com/lesson/crawler_ex03/pw_list/'# 登录记账本def login_fun(): s = requests.Session() s.get(login_website) # 访问登录页面获取登录要用的csrftoken token1 = s.cookies['csrftoken'] # 保存csrftoken # 将csrftoekn存入字段csrfmiddlewaretoken dataWebsite1 = {'username': 'user', 'password': 'password', 'csrfmiddlewaretoken': token1 } s.post(login_website, data=dataWebsite1) return sclass MyThread(Thread): def __init__(self, s): Thread.__init__(self) self.s = s def run(self): global count global pwdlist global exit ruler = re.compile(r'.*>(\d*)<.*') # 提取密码位置和值的正则表达式 while count < 100: pwdpage = s.get(pwd_website).content password_pos = BeautifulSoup(pwdpage, 'html.parser').findAll('td', {'title': 'password_pos'}) password_val = BeautifulSoup(pwdpage, 'html.parser').findAll('td', {'title': 'password_val'}) password_pos_list = [] # 密码位置list password_val_list = [] # 密码值list if password_pos: for i in password_pos: password_pos_list.append(ruler.findall(str(i))[0]) for j in password_val: password_val_list.append(ruler.findall(str(j))[0]) print self.name print password_pos_list print password_val_list for index in range(0, len(password_pos_list)): if pwdlist[int(password_pos_list[index]) - 1] == 'x': count += 1 pwdlist[int(password_pos_list[index]) - 1] = password_val_list[index] print count if exit == 0: exit = 1 print ''.join(pwdlist)if __name__ == '__main__': s = login_fun() exit = 0 count = 0 pwdlist = ['x' for i in range(0, 100)] for i in range(0, 20): # 线程数,可自定义 thread = MyThread(s) thread.start()
正确密码:5251693147792557930332653149016366877456628817361853825367526497233818308674451353577489506952443295
- 黑板客爬虫闯关第四关
- 黑板客爬虫闯关第四关
- 黑板课爬虫闯关第四关
- 黑板客爬虫闯关第二关
- 黑板客爬虫闯关第三关
- 黑板客爬虫闯关的第一关
- 黑板客爬虫闯关第二关
- 黑板客爬虫闯关-第一关
- 黑板客爬虫闯关
- 黑板课爬虫闯关第一关
- 黑板课爬虫闯关第三关
- 黑板课爬虫闯关第一关
- 黑板课爬虫闯关第二关
- 黑板课爬虫闯关第三关
- 黑板客 -- 爬虫闯关 -- 关卡01
- 黑板客 -- 爬虫闯关 -- 关卡02
- 黑板客 -- 爬虫闯关 -- 关卡03
- 黑板客 -- 爬虫闯关 -- 关卡04
- Zookeeper全解析——Paxos作为灵魂(转)
- Zookeeper全解析——Client端(转)
- 很不错的开源ERP ,ODOO , 你也来试试
- zookeeper系列之通信模型(转)
- 802.11n 协议浅析
- 黑板客爬虫闯关第四关
- (多线程)DanLi
- MFC实现程序托盘
- ORA-01461:仅能绑定要插入 LONG 列的 LONG 值
- 简析Android的垃圾回收与内存泄露
- HBase使用场景和成功案例 (转)
- Linux时间函数之 gettimeofday() 函数之使用方法
- Qt信号槽
- 多线程底层的实现