python 黑板课爬虫闯关-第四关
这关我慢慢悠悠的做了两天才搞出来,思路太重要了;下面是我最终的代码,写的很烂很low,凑合看吧。这过程中走了不少弯路,思路有问题,给自己出了不少难题,最后发现是自己想复杂了。
用到的技术:
字符串、列表、集合、字典等基础操作
requests模块的get、post、session等用法
多线程、以及获取多线程返回值
import re,requests,timefrom lxml import html
etree=html.etree
import threading
class MyThread(threading.Thread):
def __init__(self,func,args=()):
super(MyThread,self).__init__()
self.func = func
self.args = args
def run(self):
self.result = self.func(*self.args)
def get_result(self):
try:
return self.result # 如果子线程不使用join方法,此处可能会报没有self.result的错误
except Exception:
return None
def main():
# 访问第三关自动跳转到了这个url,所以首先需要登录
url_login = 'http://www.heibanke.com/accounts/login/?next=/lesson/crawler_ex03/'
# 登录成功后,访问第三关url
url = 'http://www.heibanke.com/lesson/crawler_ex03/'
# 因为需要通过带着cookie去访问,以便做到会话保持,所以这里用requests.session来做
session = requests.Session()
# 获取cookie
session.get(url_login)
# 获取csrftoken
token = session.cookies['csrftoken']
# 将用户名密码和csrftoken一起提交给登录页面
session.post(url_login, data={'csrfmiddlewaretoken': token, 'username': 'tianlegg', 'password': '123456'})
# 登录成功后,携带了token再来访问页面会看到第三关内容,和第二关一样,只不过每次提交时同样需要带着csrftoken,否则还是会报错
l=[]
count=0
while True:
thread_list = []
# 网站有限制,每个请求都会夯住15s,并且15秒内的并发最大为2,超出的话就会返回404,所以这里就起2个线程去请求
for i in range(2):
t = MyThread(get_pos_values, args=(session,))
thread_list.append(t)
t.start()
for my_thread in thread_list:
my_thread.join() # 一定要join,不然主线程比子线程跑的快,会拿不到结果
print('多线程运行结果:',my_thread.get_result())
# 把每次双线程运行返回的列表++
l = l + my_thread.get_result()
print('本轮累加的pos+pwd列表,长度:',len(l),l)
# k是所有pos
k=l[::2]
# v是所有value
v=l[1::2]
# 当去重后pos的长度为100时,说明1-100已经够了
if len(set(k))==100:
# 把pos和value合并为字典,字典中不会出现重复的key,所以不需要再去重了。
dic=dict(zip(k, v))
session.get(url)
new_token = session.cookies['csrftoken']
# 循环1-100,作为key,去获取字典中的value最后拼接起来
password=''.join([dic[str(i)] for i in range(1, 101)])
print('over!,密码是:',password)
# 将csrftoken和用户名密码一同提交
page_text=session.post(url=url,data={'csrfmiddlewaretoken': new_token, 'username': 'tianlegg', 'password': password}).text
# 通过xpath获取通关文本,下一关url并没有在页面里,自己在去访问ex04吧
tree=etree.HTML(page_text)
print(tree.xpath('//h3/text()')[0])
break
count=count+1
print(f'第{count}轮循环\n去重后的长度{len(sorted(set(k),key=int))} pos:{sorted(set(k),key=int)}')
def get_pos_values(session):
'''
获取页面中的pos和pwd并返回list
:param session:
:return:
'''
page_text=session.get(url='http://www.heibanke.com/lesson/crawler_ex03/pw_list/').text
tree = etree.HTML(page_text)
return tree.xpath('//table[@class="table table-striped"]//td/text()')
if __name__ == '__main__':
main()
开始运行时:
多线程运行结果: ['38', '8', '97', '6', '34', '7', '83', '5', '84', '7', '79', '1', '71', '2', '72', '5']多线程运行结果: ['69', '0', '22', '6', '15', '9', '73', '3', '76', '1', '9', '4', '53', '4', '67', '3']
本轮累加的pos+pwd列表,长度: 32 ['38', '8', '97', '6', '34', '7', '83', '5', '84', '7', '79', '1', '71', '2', '72', '5', '69', '0', '22', '6', '15', '9', '73', '3', '76', '1', '9', '4', '53', '4', '67', '3']
第1轮循环
去重后的长度16 pos:['9', '15', '22', '34', '38', '53', '67', '69', '71', '72', '73', '76', '79', '83', '84', '97']
结果:(跑了50次15秒才获取完1-100的pos,这个次数是随机的,这里通过多线程已经缩短了一半的时间)
密码是4894613647990394874326048437134877661813696344916326470648993670283105253381901613579433963964296911
以上是 python 黑板课爬虫闯关-第四关 的全部内容, 来源链接: utcz.com/z/386888.html