小爬虫,线程,进程?

来源:互联网 发布:程序员能干到多少岁 编辑:程序博客网 时间:2024/05/17 07:19

今天需要写一个功能,需要爬350万个url,并且做解析。
初步探明,被爬网站没有反爬策略,所以剩下的就是如何快速爬取。

选择多进程

通过redis,multiprocessing运行,发现结果有问题,
原因如下:

array = list(conn.smembers("city_key"))

array有350万个
由于是多进程,每一个进程都运行
share = array[int(index * part) : int((index + 1) * part)]
所以,每个进程都拷贝了一份array,300多万个array,直接就是350万* 100(个进程) = 3.5亿个, 我的笔记本直接内存不足。。。

import requestsimport redisfrom multiprocessing import Processconn = redis.StrictRedis(host='127.0.0.1')array = list(conn.smembers("city_key"))size = len(array)part = size * 1.0  / 100def crawl(url):    result = None    result = crawl_sub(url)     if result:        conn.sadd("city_result_key", result)def get_url(share):    for item in share:        crawl(item)if __name__ == "__main__":    jobs = []    for one in range(100):        p = Process(target=get_url, args=(array[int(index * part) : int((index + 1) * part)],))        p.start()        jobs.append(p)    for p in jobs:        p.join()

痛定思痛,决定用python的gevent协程。直接轻松加愉快,不再有内存爆炸问题了。

import redisfrom gevent import monkeyfrom gevent.pool import Poolmonkey.patch_all()pool = Pool(100)size = len(array)part = size * 1.0  / 100conn = redis.StrictRedis(host='127.0.0.1')array = list(conn.smembers("city_key"))def crawl(url):    result = crawl_sub(url)    if result:        conn.sadd("city_result_key", result)def get_url(index):    share = array[int(index * part) : int((index + 1) * part)]    for item in share:        crawl(item)if __name__ == "__main__":    for one in range(100):        pool.spawn(get_url, one)    pool.join()
0 0
原创粉丝点击