• python 黑板课爬虫闯关-第四关


    这关我慢慢悠悠的做了两天才搞出来,思路太重要了;下面是我最终的代码,写的很烂很low,凑合看吧。这过程中走了不少弯路,思路有问题,给自己出了不少难题,最后发现是自己想复杂了。

    用到的技术:

    字符串、列表、集合、字典等基础操作

    requests模块的get、post、session等用法

    多线程、以及获取多线程返回值

    import re,requests,time
    from 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}轮循环
    去重后的长度{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 

  • 相关阅读:
    数据表与简单Java类(多对多的关系)
    数据表与简单java类(一对多的关系)
    微信二次开发SDK使用教程--手机朋友圈评论删除任务反馈通知服务端
    微信二次开发SDK使用教程--手机检测到有人评论/删除朋友圈通知服务端
    微信二次开发SDK使用教程--手机检测到有人点赞/取消点赞通知服务端
    微信二次开发sdk使用教程--手机上删除朋友圈通知服务端
    微信二次开发sdk使用教程--手机上发送了朋友圈通知服务端
    微信二次开发SDK教程--上传手机客户端上微信的二维码给服务端
    微信开发SDK使用教程--手机微信个人号移除好友通知服务端
    微信开发SDK使用教程--手机微信个人号新增好友通知服务端
  • 原文地址:https://www.cnblogs.com/tianleblog/p/11599305.html
Copyright © 2020-2023  润新知