python 多线程爬虫 实例

多进程 Multiprocessing 模块

Process 类用来描述一个进程对象。创建子进程的时候,只需要传入一个执行函数和函数的参数即可完成 Process 示例的创建。

  • star() 方法启动进程,
  • join() 方法实现进程间的同步,等待所有进程退出。
  • close() 用来阻止多余的进程涌入进程池 Pool 造成进程阻塞。
multiprocessing.Process(group=None, target=None, name=None, args=(), kwargs={}, *, daemon=None)
  • target 是函数名字,需要调用的函数
  • args 函数需要的参数,以 tuple 的形式传入

=======================================================================

Pool

Pool 可以提供指定数量的进程供用户使用,默认是 CPU 核数。当有新的请求提交到 Poll 的时候,如果池子没有满,会创建一个进程来执行,否则就会让该请求等待。 
- Pool 对象调用 join 方法会等待所有的子进程执行完毕 
- 调用 join 方法之前,必须调用 close 
- 调用 close 之后就不能继续添加新的 Process 了

pool.apply_async

apply_async 方法用来同步执行进程,允许多个进程同时进入池子。

pool.apply

apply(func[, args[, kwds]])

该方法只能允许一个进程进入池子,在一个进程结束之后,另外一个进程才可以进入池子。

下面就使用  Multiprocessing  和异步来做一个爬虫例子,直接上代码

  # coding:utf-8

from common.contest import *

def spider(resultList):

    item_url = resultList['item_url']

    headers = {
        "cookie":"trctestcookie=ok; __ssid=0b09cf20-bcab-438c-9d06-3346409a800c;
    mp_invaluable_mixpanel=%7B%22distinct_id%22%3A%20%22161c7298aeabc-0da7fd442d45f7-5d1b3316-13c680-161c7298aeba04%22%7D;
     LANG-PROD=en-us; SHOW-ALERT=true; trctestcookie=ok; mp_mixpanel__c=45; afCustomerRef-prod=13LVMZ0E4C; afCustomerID-prod=4119514;
     afRememberMe=true; AZTOKEN-PROD=FAFE3733-2B21-4AC8-B127-3325BAE38594; oas-node-sid=s%3Az-KLM1REtfG-7_mRAJ3HAyv0ZFBbkSwu.
    YNq3143hCV%2FWZz0Zd15Q5g7u8aM6ARLoTOujSQnXSqQ; _gat=1; _ga=GA1.2.1505142091.1519353908;
    _gid=GA1.2.538844093.1519464821; _gat_UA-21191163-1=1; AUTHORIZATION=b3f7a9d1%2D75c3%2D425b%2Db16d%2D262135cf4dfa;
    OASTOKEN-PROD=FAFE3733%2D2B21%2D4AC8%2DB127%2D3325BAE38594; CUSTOMERID=4119514; CUSTOMERREF=13LVMZ0E4C; myinvaluablenav=1;
    _evgn_d902=%7B%22puid%22%3A%22AkLKM_odiDX3b9MMOOYEiDupItJqc6Ji2gO3amra_Qo%22%7D; _evga_d902=da0bcc787c51cd99.04r;
} try: result = session.get(url=item_url,verify=False,headers=headers).content except: result = session.get(url=item_url, verify=False,headers=headers).content soup = BeautifulSoup(result, 'html.parser') result_div = soup.find_all('div', attrs={"id": "lotPanel1"})[0] result_replace = replace(result_div) item_desc = re.findall('<b>Description:</b>(.*?)</div><a class="rfi-modal-trigger-link"',result_replace)[0] print item_desc result1 = result.replace(' ','').replace(' ','').replace(' ','') hashcode = md5(str(item_url)) create_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(time.time())) data2 = { "item_desc":str(item_desc), # "html":str(result), "hashcode": hashcode, "create_time": create_time, } null = "" item_data = (eval(json.dumps(resultList))) item_data.pop('hashcode') item_data.pop('create_time') data_dict = dict(resultList,**data2) dbName = "oversea_invaluable_2017_2_detail_info"
  # 本方法已经封装,插入数据到数据库中去
result1 = insert_data(dbName, data_dict) if __name__ == "__main__": time1 = time.time() sql = """ SELECT * FROM `oversea_invaluable_2017_2_no_detail_info` limit 1000 """
  
   #select_data是数据库查询方法,查询结果是 [{},{},{},{}, .........] resultList = select_data(sql) pool = multiprocessing.Pool(4) for item in resultList: pool.apply_async(spider, (item,)) pool.close() pool.join() print time.time()-time1
多进程虽然为我们爬取网页提供了便利,但是不建议使用,因为这样会对目标网站造成压力,如果时间充足的话,尽量利用单进程慢慢的爬取
原文地址:https://www.cnblogs.com/xuchunlin/p/7235994.html