题意再理解
本关的题目内容,这里再简单说一下:不清楚的翻下历史。
页面给出了闯关所需密码的随机位置,以及该位置的值,我们需要遍历所有页面,获取到 100 位的密码。
其中,值得注意的两点:
每一页的载入速度非常慢(正如页面内容所述),大约需要 15 秒,这是黑板课后台故意设置的;
每个页面是动态加载的,每次获取到的密码的位置并不是相同的,也就是检索完 13 页数据也不能得到 100 位的密码,需要重复检索以得到其余位置的密码。
由此可见,必须使用多线程才能迅速得到密码。
闯关思路
多线程编程使用 threading 模块,登录过程和第 3 关一样,基本只需要在第 3 关的基本上增加获取密码的功能就可以了。
初始化一个字典,用来存放密码;
每个线程都不断获取页面的全部位置和值,并将它们更新到字典中;
判断字典长度,如果字典的长度小于 100,则继续抓取页面数据并跟新字典,直到长度满足 100;
将字典中的数据转换为字符串,然后通过 post 提交到服务器进行登录;
实现
# coding=utf-8import requests, bs4import threadingimport timedef login(): # 登录URL,获取cookie login_url = 'http://www.heibanke.com/accounts/login/?next=/lesson/crawler_ex03/' login_data = {'username':'liuhaha', 'password':'123456'} # 获取默认cookie response = requests.get(url) if response.status_code == 200: print('Welcome') cookies = response.cookies # 登录 login_data['csrfmiddlewaretoken'] = cookies['csrftoken'] login_response = requests.post(login_url, allow_redirects=False, data=login_data, cookies=cookies) if login_response.status_code == 200: print('login sucessfully') return login_response.cookiesdef getPassword(page): global pwd_data payload['page'] = page print(threading.currentThread().getName() + ', loading %s?page=%s ...' %(pwd_url, page)) pwd_response = requests.get(pwd_url, cookies=cookies, params=payload) soup = bs4.BeautifulSoup(pwd_response.text, "html.parser") pwd_pos = soup.findAll('td', {'title':'password_pos'}) pwd_value = soup.findAll('td', {'title':'password_val'}) for index in range(len(pwd_pos)): pwd_data[int(pwd_pos[index].getText())] = pwd_value[index].getText() print(threading.currentThread().getName() + ', now the pwd_data length is %s' % len(pwd_data)) class MyThread(threading.Thread): def __init__(self, s): threading.Thread.__init__(self) self.s = s def run(self): global pwd_data global count while len(pwd_data) < 100: count += 1 print('The sub-thread has run %s times' % count) getPassword(count % 13) if __name__ == '__main__': start = time.time() payload = {} # 存放密码键值对 pwd_data = {} # 记录运行次数 count = 0 # 题目URL url = 'http://www.heibanke.com/lesson/crawler_ex03/' # 获取密码URL pwd_url = 'http://www.heibanke.com/lesson/crawler_ex03/pw_list/' # 获取登录成功后的cookie cookies = login() threads = [] for i in range(0, 5): # 线程数,可自定义 thread = MyThread(cookies) threads.append(thread) thread.start() # 等待所有线程完成 for thread in threads: thread.join() # 拼接password password = '' for key in sorted(pwd_data.keys()): password = password + pwd_data[key] print(password) # 重新登录 playload = {'username':'liuhaha', 'password':password} playload['csrfmiddlewaretoken'] = cookies['csrftoken'] r = requests.post(url, data=playload, cookies=cookies) print(u'执行结果:' + str(r.status_code)) if r.status_code == 200: # print(r.text) if u"成功" in r.text: print(u'闯关成功!密码为:' + password) print(u'用时 %s s' % (time.time() - start)) # break else: print(u'Failed')
作者:hoxis
链接:https://www.jianshu.com/p/44285c730bd4
點(diǎn)擊查看更多內(nèi)容
為 TA 點(diǎn)贊
評(píng)論
評(píng)論
共同學(xué)習(xí),寫(xiě)下你的評(píng)論
評(píng)論加載中...
作者其他優(yōu)質(zhì)文章
正在加載中
感謝您的支持,我會(huì)繼續(xù)努力的~
掃碼打賞,你說(shuō)多少就多少
贊賞金額會(huì)直接到老師賬戶
支付方式
打開(kāi)微信掃一掃,即可進(jìn)行掃碼打賞哦