Skip to content

Python学习记录(五):多线程&网络爬虫 #6

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
PyxYuYu opened this issue Mar 7, 2016 · 0 comments
Open

Python学习记录(五):多线程&网络爬虫 #6

PyxYuYu opened this issue Mar 7, 2016 · 0 comments

Comments

@PyxYuYu
Copy link
Owner

PyxYuYu commented Mar 7, 2016

You have to believe in yourself, that's the secret of success.

0x01 Wooyun

  • 设计缺陷/逻辑错误
    • 任意用户密码重置
      • 点击获取验证码,抓包,包中直接返回了验证码
    • 任意用户密码重置二
      • 密码找回处,输入密码找回问题答案(随便输入),抓包,修改返回消息体中的errType 为0(不带双引号),发出这个包,修改密码
  • CSRF
    • JSONP 劫持
  • 未授权访问/权限绕过
    • Jenkins系统未授权访问可执行系统命令
  • SQL注入
0x02 爬虫实战一

  • 多线程的实现
    • 线程之前共享状态、内存、资源,并且他们相互间易于通信
    • Queue模块:提供了一个适用于多线程编程的先进先出数据结构,可以用来安全的传递多线程信息
    • 三类队列:
      • FIFOFirst In First Out,最早加入的任务会被最先得到
        • class Queue.Queue(maxsize=0)
        • maxsize是个整数指明了队列中能存放数据个数的上限,一旦达到上限,插入会导致阻塞,直到队列中的数据被消费掉,如果maxsize小于或等于0,队列大小没有限制。
      • LIFOLast In First Out,最后加入的任务会被最先得到(就像栈一样)
        • class Queue.LifoQueue(maxsize=0)
        • maxsize是个整数指明了队列中能存放数据个数的上限,一旦达到上限,插入会导致阻塞,直到队列中的数据被消费掉,如果maxsize小于或等于0,队列大小没有限制。
      • 优先队列:任务被保持有序(使用heapq模块),拥有最小值的任务(优先级最高)被最先得到
        • class Queue.PriorityQueue(maxsize=0)
    • Queue对象(QueueLifoQueuePriorityQueue
      • Queue.qsize()返回队列的近似大小,队列大小大于0并不保证接下来的get()调用不会被阻塞,队列大小小于maxsize也不保证接下来的put()调用不会被阻塞
    • Queue.empty()队列为空,返回True,否则False。如果返回True并不能保证接下来的put()调用不会被阻塞,False也不保证get()不会被阻塞
    • Queue.full()队列是满的返回True,否则返回False,如果返回True并不能保证接下来的get()不会阻塞,False也不能保证put()不会被阻塞
    • Queue.put(item[,block[,timeout]])
      • item放入队列中,如果可选参数block为真且timeout为空对象(默认的情况,阻塞调用,无超时),如有必要(比如队列满),阻塞调用线程,直到有空闲槽可用。如果timeout是个正整数,阻塞调用进程最多timeout秒,如果一直无空闲槽可用,抛出Full异常(带超时的阻塞调用)。如果block为假,如果有空闲槽可用将数据放入队列,否则立即抛出Full异常(非阻塞调用,timeout被忽略)
      • 也就是在队列的尾部插入一个项目
    • Queue.put_nowait(itme) 等同于put(item,False)(非阻塞调用)
    • Queue.get([block[,timeout]])
      • 从队列中移除并返回一个数据,如果可选参数block为真且timeout为空对象(默认的情况,阻塞调用,无超时),阻塞调用进程直到有数据可用,如果timeout是正整数,阻塞调用进程最多timeout秒,如果一直无数据可用,抛出Empty异常(带超时的阻塞调用),如果block为假,如果有数据可用返回数据,否则立即抛出Empty异常(非阻塞调用,timeout被忽略)
      • 也就是在队列头部删除并且返回一个项目
    • Queue.get_nowait()等同于get(False)
    • 为了跟着入队任务被消费者线程完全的处理掉,Queue对象提供了两个额外的方法
      • Queue.task_done()
        • 意味着之前入队的一个任务已经完成,由队列的消费者线程调用,每一个get()调用得到一个任务,接下来的task_done()调用告诉队列该任务已经处理完毕。如果当前一个join()正在阻塞,它将在队列中的所有任务都处理完时恢复执行(即每一个由put()调用入队的任务都有一个对应的task_done()调用)。如果该方法被调用的次数多于被放入队列中的任务的个数,ValueError异常会被抛出。
      • Queue.join()
        • 阻塞调用线程,直到队列中的所有任务被处理掉。只要有数据被加入队列,未完成的任务数就会增加。当消费者线程调用task_done()(意味着有消费者取得任务并完成任务),未完成的任务数就会减少。当未完成的任务数降到0,join()解除阻塞。
from Queue import Queue

# FIFO模式,先进先出
q = Queue()

for i in range(8):
    q.put(i)
while not q.empty():
    print q.get(),
  • threading模块
    • Thread对象 表示在单独的一个控制线程中运行的一个活动,有两种指定活动的方法
      • 通过传递一个可调用对象给构造函数
      • 在子类中覆盖run()方法(注意: 在子类中不应该覆盖其他方法(构造函数除外),只能覆盖__init__()run()方法)
    • 一个线程对象创建后,它的活动必须通过调用线程的start()方法启动,它在单独的一个控制线程中调用run()方法
    • threading.Thread(group=None,target=None,name=None,args=(),kwargs={})
      • groupNone,被保留用于未来实现ThradGroup类时的扩展
      • target是将run()方法调用的可调用对象,默认None,表示不调用任何东西
      • name是线程名字
      • args是给调用目标的参数元组,默认()
      • kwargs是给调用目标的关键字参数的一个字典,默认{}
#!/usr/bin/env python
# coding=utf-8

from threading import Thread
from Queue import Queue
import urllib2

hosts = [ 'http://www.baidu.com', 'http://news.163.com/', 'http://weibo.com/', 'http://blog.163.com' ]
#创建一个类继承Thread类
class TestThread(Thread):
    # 重写构造函数,继承Thread
    def __init__(self, queue):
        Thread.__init__(self)
        self.queue = queue
    # 重写run()函数
    def run(self):
        while 1:
            host = self.queue.get()
            res = urllb2.urlopen(host)
            print res.read(200)
            print '**' * 20
            self.queue.task_done()

def main():
    q = Queue()
    for host in hosts:
        q.put(host) 
    for i in range(len(hosts)):
        t = TestThread(q)
        t.setDaemon(True)
        t.start()
    # 阻塞调用线程,直到队列中任务全部处理完成
    q.join()    

if __name__ == '__main__':
    main()
  • BeeBeeto爬虫多线程分析
    • 需要3个线程,A线程爬主要的页面,B线程爬POC具体内容,C线程保存POC到txt文档
    • A线程通过POC的url和B线程通信,B线程通过具体内容和C线程通信,所以A线程必定最早结束,然后是B,然后是C,B和C结束之前必须完成所有的内容(生产者和消费者的关系,生产者生产出的数据,后面的消费者必须完全消费)
    • 有共享区域,需要使用Lock
0x03 一天总结

  • 线程和队列一起运用,还需要继续学习,理解
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant