python学习笔记(八)协程、爬取网页

来源:互联网 发布:淘宝权限管理 编辑:程序博客网 时间:2024/06/06 08:45

协程又叫微线程,但与线程是完全不同的概念。线程之间是并发的,开发者不知道它们在什么时候切换;而协程是属于一个线程的,它们之间的切换开发者是明确的。在介绍完协程后会给出一个使用urllib爬取网页中图片的地址的例子演示协程。

开始

一个函数:

def func():    for i in range(1,10):        return i

只会执行一次返回,如果要得到1~10的数据只能返回一个列表。但如果将return改为另一种写法,就可以分次得到:

def func():    for i in range(1,10):        yield i

使用yield返回数据的函数叫做生成器,它可以通过如下方法不断获取值:

f = func()f.next()f.next()

如果该生成器要不断获得外界值,也可以使用yield来获取:

def func():    r = 0    n = yield r    if not n:        return    for i in range(1,10):        yield i

外界通过send方法传入值:

f = func()f.send(5)f.next()f.next()

可以将该函数作为参数传入另一个高阶函数,协作运行:

def func2(f)    f = func()    f.send(5)    print f.next()    print f.next()

这种形式的程序就叫做协程。

一个例子

import urllibimport re#this function is slow, use thread to costume more cpudef get_html(url):    page = urllib.urlopen(url)    return page.read()addr_pattern = re.compile(r'\/[^\/]+;illust_id\=\d+')pic_pattern = re.compile(r'http[^\>]*\.jpg')#an address has many pictures,so find the patterndef get_addr(html):    global addr_pattern    while(1):        print type(html)        s = '1'        if(type(html)!=type(s)):            html = yield ''            continue        strs = re.split(r'\n',html)        for s in strs:            m = addr_pattern.search(s)            if(m):                yield m.group()        #over        html = yield ''#an address has only one picture, get its addressdef get_pic(url):    global pic_pattern    m = pic_pattern.search(get_html(url))    print m    if(m):        return m.group()def mainfunc():    url = 'https://www.pixiv.net/search.php?word=Fate%2FGrandOrder&s_mode=s_tag_full&order=date_d&p='    fout = open('address.txt','a')    page = 1    f = get_addr(get_html(url+str(page)))    while(page<5):        h = f.next()        if(h==''):            print 'page%s'%page            page = page + 1            h = f.send(get_html(url+str(page)))        h = 'https://www.pixiv.net'+h        s = get_pic(h)        if(s):            fout.write(s)            fout.write('\n\r')    fout.close()if __name__ == '__main__':    mainfunc()

功能是爬取P站的图片地址。但尝试下载图片却被拒绝访问了,问题还没能解决。

参考资料:
http://www.liaoxuefeng.com/wiki/001374738125095c955c1e6d8bb493182103fac9270762a000/0013868328689835ecd883d910145dfa8227b539725e5ed000
爬虫 http://www.cnblogs.com/fnng/p/3576154.html

0 0
原创粉丝点击