python多线程爬取

科技在发展,时代在进步,我们的CPU也越来越快,CPU抱怨,P大点事儿占了我一定的时间,其实我同时干多个活都没问题的;于是,操作系统就进入了多任务时代。我们听着音乐吃着火锅的不在是梦想。
python提供了两个模块来实现多线程thread 和threading ,thread 有一些缺点,在threading 得到了弥补,为了不浪费你和时间,所以我们直接学习threading 就可以了。

1.代码:

#coding: utf-8

import threading
import time

class Foo(threading.Thread):
    def run(self):
        print  '我开始听音乐', '\n'

        time.sleep(1)

        print '我已经听完了音乐', '\n'

def foo():
    print '我开始吃火锅', '\n'

    time.sleep(2)

    print '我已经吃完了火锅', '\n'

t = Foo()
d = threading.Thread(target = foo)
t.start()
# d.setDaemon(True)
d.start()

我们先听了一首音乐,通过Foo类来控制音乐的播放,音乐播放需要1秒钟,sleep()来控制音乐播放的时长。同时我们又看了一场电影,每一场电影需要2秒钟。输出如下图:

1.png

2. setDaemon(True):守护线程

我们在标题1的代码里面进行一些修改来体现出setDaemon的作用

#coding: utf-8

import threading
import time

class Foo(threading.Thread):
    def run(self):
        print  '我开始听音乐', '\n'

        time.sleep(1)

        print '我已经听完了音乐', '\n'

def foo():
    print '我开始吃火锅', '\n'

    time.sleep(2)

    print '我已经吃完了火锅', '\n'

t = Foo()
d = threading.Thread(target = foo)
t.start()
d.setDaemon(True)
d.start()

这里面d给设置了守护线程,2个线程同时开始,但是如果其他线程结束了,那么守护线程不管有没有完成都要结束。意思就是我们听着音乐,吃着火锅,音乐听完了,不管我们火锅有没有吃完,就得赶紧撤了。
下图是输出结果:

2.png

3.join()阻塞

继续修改我们的代码

#coding: utf-8

import threading
import time

class Foo(threading.Thread):
    def run(self):
        print  '我开始听音乐', '\n'

        time.sleep(1)

        print '我已经听完了音乐', '\n'

def foo():
    print '我开始吃火锅', '\n'

    time.sleep(2)

    print '我已经吃完了火锅', '\n'

t = Foo()
d = threading.Thread(target = foo)
t.start()
d.setDaemon(True)
d.start()
d.join()

我们将d进行阻塞,就是t执行完成,你才能执行d,也就是我们必须听完音乐,才能看电影 。
下图是输出:

3.png

4.queue队列

队列的意思是将东西放进去,可以随时取出来,下面有个代码演示:

#coding: utf-8

import Queue

q = Queue.Queue()

for i in range(5):
    q.put(i)

while not q.empty():
    print q.get()

输出结果:

4.png

这个应该很容易理解,就不用多解释。

5.使用过多线程进行网页爬取

代码如下:

#!/usr/bin/env python
# coding: utf-8

#队列自己带锁,自己阻塞,线程安全的,不用自己显式的去编写
import threading
import requests
import urllib
import Queue
from bs4 import BeautifulSoup


class Foo(threading.Thread):
    def __init__(self, queue):
        threading.Thread.__init__(self)
        self.queue = queue

    def run(self):
        while True:
            key = self.queue.get()#取key列表里面的元素
            self.baidu(key)#运行函数baidu,传的参数是key
            self.queue.task_done()#取不到元素的时候自动退出程序

    def baidu(self, keys):
        gjc = urllib.quote(keys)
        url = 'https://www.baidu.com/s?ie=utf-8&mod=1&isid=C72D6237C6C55642&ie=utf-8&f=8&rsv_bp=0&rsv_idx=1&tn=baidu&wd=' + gjc + '&rsv_pq=816a886000062c06&rsv_t=c589dMGIygeVyzfmHXpCrPrWN2S4yWp8ttSNQ77uzbcec5H1cOVF2yiedcs&rqlang=cn&rsv_enter=1&rsv_sug3=7&rsv_sug1=3&rsv_sug7=100&rsv_sug2=0&inputT=89&rsv_sug4=41058&rsv_sid=1424_21119_17001_22072&_ss=1&clist=&hsug=&f4s=1&csor=2&_cr1=28095'
        header = {  'Refer':'https://www.baidu.com/',
                'Host':'www.baidu.com',
                'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.79 Safari/537.36',
                'Cookie':'BAIDUID=75774ED511BF2DECB6C4A142D1F4CCDF:FG=1; PSTM=1499515257; BIDUPSID=DD4A04E2ED6C099A9F40EF86229306AB; FP_UID=616a141a155bdb648b37b61ff16cfdc3; BDRCVFR[yfg8b4Gp7xm]=yiTPYW-i3eTXZFWmv68mvqV; H_PS_645EC=9607I22jkjSFIiy14y6B2VlNt4TQHDqMpVs%2FNy6mdneG1NMGExHCLS0uRrs; BD_CK_SAM=1; PSINO=5; BDORZ=B490B5EBF6F3CD402E515D22BCDA1598; BD_HOME=0; H_PS_PSSID=1447_19033_13550_21095_18560_17001_22160; BD_UPN=12314753'
            }

        content = requests.get(url, headers=header).content
        soup = BeautifulSoup(content, 'html.parser')
        keyword = soup.find_all('div', id="rs")
        for i in keyword:
            print i.get_text()

if __name__ == '__main__':
    queue = Queue.Queue()
    key = ['苹果8', '小米Mx2', '华为mate10']

    for i in key:
        queue.put(i)#将key加入队列里面,用于run()的调用

    for item in range(3):
        t = Foo(queue)
        t.setDaemon(True)#守护进程,如果主线程结束,则会退出
        t.start()

    queue.join()#阻塞,函数baidu('苹果8')执行完成,才会继续进行下一次baidu('小米Mx2')

输出结果:

5.png

6.python中多线程的优缺点

多线程目前仅用于网络多线程采集, 以及性能测试。

其它的语言也有类似的情况,线程本身的特点导致线程的适用范围是受限的。只有CPU过剩,而其它的任务很慢,此时用线程才是有益的,可以很好平衡等待时间,提高并发性能。线程的问题主要是线程的安全稳定性。线程无法强制中止,同时线程与主进程共享内存,可能会影响主进程的内存管理。在python里线程出问题,可能会导致主进程崩溃。 虽然python里的线程是操作系统的真实线程。那么怎么解决呢?通过我们用进程方式。子进程崩溃后,会完全的释放所有的内存和错误状态。所以进程更安全。 另外通过进程,python可以很好的绕过GIL,这个全局锁问题。但是进程也是有局限的。不要建立超过CPU总核数的进程,否则效率也不高。简单的总结一下。当我们想实现多任务处理时,首先要想到使用multiprocessing, 但是如果觉着进程太笨重,那么就要考虑使用线程。 如果多任务处理中需要处理的太多了,可以考虑多进程,每个进程再采用多线程。如果还处理不要,就要使用轮询模式,比如使用poll event, twisted等方式。如果是GUI方式,则要通过事件机制,或者是消息机制处理,GUI使用单线程。所以在python里线程不要盲目用, 也不要滥用。 但是线程不安全是事实。如果仅仅是做几个后台任务,则可以考虑使用守护线程做。如果需要做一些危险操作,可能会崩溃的,就用子进程去做。 如果需要高度稳定性,同时并发数又不高的服务。则强烈建议用多进程的multiprocessing模块实现。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 157,298评论 4 360
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,701评论 1 290
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 107,078评论 0 237
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,687评论 0 202
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,018评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,410评论 1 211
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,729评论 2 310
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,412评论 0 194
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,124评论 1 239
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,379评论 2 242
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,903评论 1 257
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,268评论 2 251
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,894评论 3 233
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,014评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,770评论 0 192
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,435评论 2 269
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,312评论 2 260

推荐阅读更多精彩内容

  • 多线程爬取表情包 有一个网站,叫做“斗图啦”,网址是:https://www.doutula.com/。这里面包含...
    编程小蝉阅读 1,033评论 1 7
  • 1、线程和进程 计算机的核心是CPU,它承担了所有的计算任务。它就像一座工厂,时刻在运行。 假定工厂的电力有限,一...
    Andone1cc阅读 486评论 0 1
  • 线程和进程 计算机,用于计算的机器。计算机的核心是CPU,在现在多核心的电脑很常见了。为了充分利用cpu核心做计算...
    人世间阅读 24,272评论 3 85
  • 前言:为什么有人说 Python 的多线程是鸡肋,不是真正意义上的多线程? 看到这里,也许你会疑惑。这很正常,所以...
    猴哥爱读书阅读 51,511评论 6 69
  • 如果只是努力就有用的话,那其实一切就太简单了。 比如说,我告诉你,你只要拼命努力,你就可以成为马云。那我相信这世上...
    魏佳斌阅读 910评论 0 1