def receive_seed_and_start_crawl(self, seed): """接受种子 拿出url 带cookie 完成请求 """ print('\n开始抓取') url = seed.get('url') # 一个反馈,请求一个cookie print('请求种子和cookie') self.feed_back_seed(seed, cookie=False) cookie = wait_for_msg_long(ssn_que_p) data = self.user_define_request(url, cookie) # 首先验证data是有有效 if data and data != ['null']: # 先反馈 self.feed_back_seed(seed, cookie=True) # 放数据 seed.update({'data': data}) # 丢入持久化队列里 redis_cli.lpush(psm_que, dumps_json(seed)) print('有数据,放入持久化队列') else: # 反馈该cookie失效 seed.update({'cookie_status': 1}) # 这里犯了一个大错,就是cookie呢 09/10 seed.update({'cookie': cookie}) # 丢入反馈队列里 self.feed_back_seed(seed, cookie=True) print('完成反馈') # 他的生命循环完成 del seed
def push_seed_2_queue(self, seed): """ 将拿到的seed放到队列里 :return: """ que = config.task_que redis_cli.lpush(que, dumps_json(seed))
def put_cookie_2_que(self, cookie): """ 将cookie放入队列里 """ que = config.ssn_2_slv cookie = loads_json(cookie) redis_cli.lpush(que, dumps_json(cookie))
def init_mark_que(): """重置mark_que,并置mark为0""" que = config.mark_que while True: if redis_cli.exists(que): redis_cli.rpop(que) continue break # 重置 redis_cli.lpush(config.mark_que, 0)
def receive_seed_and_start_crawl(self, seed): """接受种子 拿出url 带cookie 完成请求 """ print('\nspider获取任务') url = seed.get('url') # 一个反馈,请求一个cookie print('请求种子和cookie') self.feed_back_seed(seed, session=True, seed=False) # 等待cookie cookie = wait_for_msg_long(ssn_2_slv) # 实例化请求,解析模块 rm = RequestModel(self.mark) data = rm.user_define_request(url, cookie) # 首先验证data是有有效 if data != ['redirect'] and data != ['null'] and data != []: # 先反馈, 这时候只需要向种子管理反馈 self.feed_back_seed(seed, session=False, seed=True) # 放数据 seed.update({'data': data}) # 丢入持久化队列里 print('有数据,放入持久化队列\n') redis_cli.lpush(slv_2_psm, dumps_json(seed)) elif data == ['redirect']: # 反馈该cookie失效, 需要向两个队列同时反馈 seed_b = deepcopy(seed) seed_b.update({'cookie_status': 1}) # 这里犯了一个大错,就是cookie呢 09/10 seed_b.update({'cookie': cookie}) # 丢入反馈队列里 self.feed_back_seed(seed_b, session=True, seed=True) print('cookie失效,完成反馈\n') del seed_b else: # 没有数据,cookie仍旧是有效的 # 只需要向种子管理反馈 self.feed_back_seed(seed, session=False, seed=True) print('没有数据, 完成反馈\n') # 他的生命循环完成 del seed del rm
def start_node_in_order(cmd): """ 将指定的命令放入队里 """ que = config.task_que order = { 'ssnm': {'cmd': {'command': 'ssnm'}, 'name': 'SessionMangement'}, 'sedm': {'cmd': {'command': 'sedm'}, 'name': 'SeedMangement'}, 'psm': {'cmd': {'command': 'psm'}, 'name': 'PersistenceMangement'} } print('启动\t{0}'.format(order.get(cmd).get('name'))) redis_cli.lpush(que, dumps_json(order.get(cmd).get('cmd'))) # 等待回馈 wait_feed_back() print('完成启动') return
def listn_the_psm_que(): """持续监听psm_que这个队列 只要一有数据过来,就做存储 """ # 先反馈 # 完成后像队里推送一条已完成启动 print('持久化队列启动') que = config.task_que_fb ctx = dumps_json({'psm': 'done'}) redis_cli.lpush(que, ctx) while True: if redis_cli.exists(psm_que): # 就开始处理 token_set = make_set(token, blank='', index='') msg = redis_cli.rpop(psm_que) seed = loads_json(translate_2_json_dict(msg)) print('{0}\t收到数据'.format( datetime.datetime.today().strftime('%Y-%m-%d %H:%M:%S'))) # 接下来就是做持久化处理了 do_persistence(seed, token_set) time.sleep(0.1)
def seed_main_logic(self): """ 主要处理逻辑 1. 生产种子 2. 提取种子 3. 检测状态 """ print('seed管理已启动') # 完成后像队里推送一条已完成启动 que = config.task_que_fb ctx = dumps_json({'sedm': 'done'}) redis_cli.lpush(que, ctx) # 更新车系 update_brands_serise() # 第一步就是生产种子 print('生产种子') self.seeds_maker() # 完了后先丢20个种子 self.decide_push_seed_2_queue(0) # 开始监听队列,准备投放种子 slv_2_sed = config.slv_2_sed while True: msg = wait_for_msg_long(slv_2_sed) print('{0}\t接收反馈'.format( datetime.datetime.today().strftime('%Y-%m-%d %H:%M:%S'))) if msg: # 开始处理这个反馈 # 主要看 cookie_status is_deal = self.deal_feed_back(msg) if is_deal: msg.update({'cookie_status': 0}) self.push_seed_2_queue(msg) continue else: # 通过的话,则上传一个新的种子 self.decide_push_seed_2_queue(1) print('完成推送') time.sleep(0.1)
def session_main_logic(self): """ 由slave调用的部分 实例化后,实现登录 在 删除,导入列表时候通过消息通信来完成 需要加一个结束模块 #09-05 解决bug 等待机制: 当收到第一个请求触发 统计数量 放入队列 """ print('session管理已启动') # 实例化我们的种子模块,并开始登录 self.logic_add_cookie() # # 并把所有的cookie都扔到消息队列里去 # self.decide_psuh_cookie_2_que(0) # 完成后像队里推送一条已完成启动 que = config.task_que_fb ctx = dumps_json({'ssnm': 'done'}) redis_cli.lpush(que, ctx) # 开始监听反馈队列 print('开始监听ssn_req队列') slv_2_ssn = config.slv_2_ssn while True: msg_list = [] msg = wait_for_msg_long(slv_2_ssn) print(datetime.datetime.today().strftime('%Y-%m-%d %H:%M:%S'), '\t接受反馈') msg_list.append(msg) # 只要有消息来了,先处理,再就发一条cookie出去 is_deal = self.deal_feed_back(msg_list) if not is_deal: self.decide_psuh_cookie_2_que(1) print('完成cookie派发\n') """
def feed_back_seed(self, ctx, session, seed): """向seesion和seed管理反馈 session=True时候,需要向session管理发送 seed=True时候,需要向seed管理推送 """ if session and seed: redis_cli.lpush(slv_2_sed, dumps_json(ctx)) redis_cli.lpush(slv_2_ssn, dumps_json(ctx)) elif session and not seed: redis_cli.lpush(slv_2_ssn, dumps_json(ctx)) else: redis_cli.lpush(slv_2_sed, dumps_json(ctx)) return # if __name__ == '__main__': # seed = {"brand_id": "1199", "brand": "奥迪", "serise_id": "2614", "serise": "奥迪A5", "p_type": "合资", "url": "https://www.guazi.com/xinyang/dealrecord?tag_id=22288&date=2017100", "check_city": "xinyang", "date": "2018-1", "cookie": {}, "data": [], "cookie_status": 0, "epoh": 0} # cookie = {"clueSourceCode": "%2A%2300", "preTime": "%7B%22last%22%3A1537928136%2C%22this%22%3A1537928136%2C%22pre%22%3A1537928136%7D", "GZ_TOKEN": "ef52toYlCiG36xYV8f3011%2BZVJgkcTK8eTkkn31WYGulmX9gKIByhmHZp1d6sg%2BtwJ3L0CbW2avGHetiKQLSM5EvM90l2XbOHFMZs97irvp8flsdbMTJlK1okNg8BAtx6RkhoQ%2BhbwYPAaLDLw", "guaZiUserInfo": "0MSnBkg0hdYQNXvlLOYi2", "userid": "620499844"} # sh = SpiderHandler('1') # # sh.receive_seed_and_start_crawl(seed) # sh.demo(seed, cookie)
def listen_task_que(): """启动后 开始监听 Task_Que 拿到任务,先弄清是是个啥 在转换自己的角色 正常的种子 {"url": "xxxx", ......} 任务: {"command": "xxxx"} session管理: ssnm seed管理: sedm persistence管理: psm # 09-07更新。需要为每一个节点打上一个标记 为了不放js文件混乱,才这样的。 """ task_que = config.task_que mark_que = config.mark_que # 在监听任务前,需要先监听mark_que # 具体就是,从mark队列里拿到数字标号 # 自增1作为自己的标号 # 同时将自己的标号放入mark队列里 # 先监听mark队列,拿到自己的编号 while True: if redis_cli.exists(mark_que): msg = redis_cli.rpop(mark_que) if not msg: continue mark = int(msg.decode()) + 1 break time.sleep(random.random()) # 放入队列里 redis_cli.lpush(mark_que, mark) print('当前slave编号\t{0}'.format(mark)) # 完成了后,才开始监听这个任务队列 while True: if redis_cli.exists(task_que): msg = redis_cli.rpop(task_que) # 开始分类msg属于什么任务: # if not msg: continue msg_dict = loads_json(msg.decode()) print('{0}\t收到数据'.format( datetime.datetime.today().strftime('%Y-%m-%d %H:%M:%S'))) # 开始分类: if msg_dict.get('command'): # 这里commend commend = msg_dict.get('command') if commend == 'ssnm': sm = SessionMangement() sm.session_main_logic() elif commend == 'sedm': sm = SeedsMangement() sm.seed_main_logic() else: # 化身持久化模块 listn_the_psm_que() else: # 那就是种子了 # 这里要做的事情有 # 1. 请求一个cookie # 2. 完成html的请求 # 3. data放入psm队列里 # 4. 反馈给seesion/seed模块 time.sleep(random.random() * 10) seed = msg_dict # 调度spider, 把mark放入实例化中 sp = SpiderHandler(mark) sp.receive_seed_and_start_crawl(seed) # 结束上一个,等下一个种子 del sp time.sleep(0.1)
def feed_back_seed(self, seed, cookie): """向seesion和seed管理反馈""" redis_cli.lpush(ssn_que, dumps_json(seed)) if cookie: redis_cli.lpush(sed_que, dumps_json(seed))