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('\r\n','').replace('\n','').replace('\r','')
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
多进程虽然为我们爬取网页提供了便利,但是不建议使用,因为这样会对目标网站造成压力,如果时间充足的话,尽量利用单进程慢慢的爬取
如果觉得对您有帮助,麻烦您点一下推荐,谢谢!
好记忆不如烂笔头
好记忆不如烂笔头