小爬虫,线程,进程?

来源:互联网 时间:1970-01-01


今天需要写一个功能,需要爬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()



相关阅读:
Top