def jude_request(self, resp): """ :return: 判断请求是否成功 如果不成功 直接采集相关措施 比如重新请求 或者操作手机获取参数 """ # 返回一个None if resp == "error": logger.error('请求失败, 未能获取到阅读数据') self.success = False return None resp_json = resp.json() # 正常 if 'appmsgstat' in resp_json: # 通过安检 stop_and_start.check({'crawler': '阅读数据', 'msg': 'success'}) self.success = True return resp # 请求频繁 # elif 'errmsg' in resp_json['base_resp']: # debug_p(resp_json) # logger.warning("获取文章阅读数据频繁等待5分钟之后继续 %s"%(self.url)) # time.sleep(5*60) # self.jude_request(self.act_request()) # 参数过期 {'advertisement_info': [], 'reward_head_imgs': []} else: logger.error("请求阅读数据参数错误 %s" % (self.url)) self.success = False return None
def insert(self, data): """ :param data:list或dict :return: 不存在插入 存在更新 同时支持单个数据和多个数据 单个数据使用dict表示 多个数据使用list表示 """ res = None if type(data) is type({}): exist = self.count('id', data['id'], _type=2) if exist == 0: self.table.create(**data) res = 'INSERT' else: self.update('id', data['id'], data) res = 'UPDATE' return res if type(data) is type([]): with sqlite_db.atomic(): for d in data: exist = self.count('id', d['id'], _type=2) if exist == 0: self.table.create(**d) res = 'INSERT' else: self.update('id', d['id'], d) res = 'UPDATE' return res logger.error('待插入的数据有误%s' % str(data)) return 'ERROR'
def l1l1111lll_wcplus_(l1l11ll1ll_wcplus_): ts = l1l1ll1l11_wcplus_.l1ll11ll1l_wcplus_() ts['total_task_num'] = l1l11ll1ll_wcplus_ result = l1l1ll1l11_wcplus_.l1l11l1ll1_wcplus_(ts) if result == None: logger.error('任务状态队列出错') exit()
def search(self): """ :return: 执行搜索动作 """ # 根据公众号的昵称 indices = [] st = deepcopy(search_template) dls = self.search_data_preprocess() st.update(dls) if self.source != None: st["_source"] = self.source # 添加搜索字段 # st['_source'] = self.fileds # 更新from 和 size 支持分页 try: st["from"] = self.from_size["from"] st["size"] = self.from_size["size"] except: logger.warning("from_size字段错误 %s"%(str(self.from_size))) # 指定 搜索的索引范围 if not self.index_list: indices = '*' else: indices = self.index_list try: result = es_instance.search(index=indices, body=st)['hits'] # result = es_instance.search(index=indices, doc_type=self.doc_type, body=st)['hits'] return result except Exception as e: print(e) logger.error("搜索错误 可能是有指定了不存在的搜索范围没有建立索引%s"%(str(indices))) return False
def search(self): """ :return: 执行搜索动作 """ indices = [] st = deepcopy(search_template) l111ll11l1_wcplus_ = self.l11l1111ll_wcplus_() st.update(l111ll11l1_wcplus_) if self.source != None: st['_source'] = self.source try: st['from'] = self.l1lll1l1ll_wcplus_['from'] st['size'] = self.l1lll1l1ll_wcplus_['size'] except: logger.warning('from_size字段错误 %s' % str(self.l1lll1l1ll_wcplus_)) if not self.index_list: indices = '*' else: indices = self.index_list try: result = (l11l111ll1_wcplus_.search(index=indices, doc_type=self.doc_type, body=st))['hits'] return result except Exception as e: print(e) logger.error('搜索错误 可能是有指定了不存在的搜索范围没有建立索引%s' % str(indices)) return False
def get(self, key): """ :param key: :return:获取一个文件文件的内容 """ try: with codecs.open(self.dir+key,'r',encoding='utf8') as f: text = f.read().replace("'",'"') except: text = None logger.error("%s文件不存在"%(self.dir+key)) return text
def jude_request(self, resp): """ :return: 判断请求是否成功 如果不成功 直接采集相关措施 比如重新请求 或者操作手机获取参数 """ resp_json = resp.json() if 'appmsgstat' in resp_json: stop_and_start.check({'crawler': '阅读数据', 'msg': 'success'}) self.success = True return resp logger.error('请求阅读数据参数错误 %s' % self.url) self.success = False return
def save(key, value, path='./'): """ :param key: :param value: :return: 将键值对保存为文件 文件路径不存在会自动创建 """ if not os.path.exists(path): os.makedirs(path) try: with codecs.open(path+str(key),'w',encoding='utf8') as f: f.write(str(value)) except: logger.error('文件保存失败%s'%(path+key))
def jude_request(self, resp): """ :param resp: 请求的原始返回结果 :return: 判断请求是否成功 如果不成功 直接采集相关措施 1. 请求结果判断如果不是有效响应则再次发起请求 2. 有可能需要更新参数 """ resp_json = resp.json() if resp_json['errmsg'] == 'ok': self.success = True return resp self.success = False logger.error('获取历史文章列表参数过期或微信被限制%s' % resp_json) return
def l1ll1l1lll_wcplus_(self, resp): """ :param resp: 请求的原始返回结果 :return: 判断请求是否成功 如果不成功 直接采集相关措施 1. 请求结果判断如果不是有效响应则再次发起请求 2. 有可能需要更新参数 """ l11llllll1_wcplus_ = resp.json() if l11llllll1_wcplus_['errmsg'] == 'ok': self.success = True return resp self.success = False logger.error('获取历史文章列表参数过期或微信被限制%s' % l11llllll1_wcplus_) return
def l1l11l1111_wcplus_(self): """ :return: 申请一个代理IP """ proxy_ip = l1ll1l1111_wcplus_() if not proxy_ip: self.l1l11l111l_wcplus_.clear() logger.error( '采集文章正文:' + 'IP地址被限制!采集文章正文已经提前结束,将导致部分文章的PDF无法导出,可24小时后再次采集,亦可联系阿呆。将继续采集阅读数据' ) l1l1ll1l11_wcplus_.l1l111l11l_wcplus_(ip=proxy_ip, l1l11lllll_wcplus_=time.time()) return proxy_ip
def index_doc(self, doc): """ :param doc:文档体 :return:新建或者更新doc """ # 只对 doc_schema 中定义的字段进行索引 part_doc = dict((key, doc[key]) for key in doc_schema) # 当公众号文章更新之后还产生新的文章 直接跳过对旧有文章的index if self.doc_exist(doc['id']) == 1: return try: es_instance.index(index=self.index_name, doc_type=self.doc_type, id=doc['content_url'], body=part_doc) except: logger.error('index 文档失败 %s'%(doc['title']))
def do_job(self): """ :return: 取出一个任务 请求html内容 """ task = self.get_q_task if task is None: return try: # 执行任务 # logger.info('正在执行任务 '+str(task)) task_handler(task) except Exception as e: logger.error("任务出错" + (str(task))) logger.error(e) self.task_q.task_done() return task
def index_doc(self, doc): """ :param doc:文档体 :return:新建或者更新doc """ l11l111lll_wcplus_ = dict( ((key, doc[key]) for key in l1llll1lll_wcplus_)) if self.l11l11l1l1_wcplus_(doc['id']) == 1: return try: l11l111ll1_wcplus_.index(index=self.index_name, doc_type=self.doc_type, id=doc['content_url'], body=l11l111lll_wcplus_) except: logger.error('index 文档失败 %s' % doc['title'])
def l1ll1l1lll_wcplus_(self, resp): """ :return: 判断请求是否成功 如果不成功 直接采集相关措施 比如重新请求 或者操作手机获取参数 """ if resp == 'error': logger.error('请求失败, 未能获取到阅读数据') self.success = False return l11llllll1_wcplus_ = resp.json() if 'appmsgstat' in l11llllll1_wcplus_: l11ll11lll_wcplus_.check({'crawler':'阅读数据', 'msg':'success'}) self.success = True return resp logger.error('请求阅读数据参数错误 %s' % self.url) self.success = False return
def insert(self, data): """ :param data:list或dict :return: 不存在插入 存在更新 同时支持单个数据和多个数据 单个数据使用dict表示 多个数据使用list表示 """ # 插入单个数据 res = None # 处理单个数据 if type(data) is type({}): # 根据id判断数据是否存在 exist = self.count('id', data['id'], _type=2) # 数据不存在 插入 if exist == 0: self.table.create(**data) res = "INSERT" # 数据存在 更新 else: self.update('id', data['id'], data) res = "UPDATE" return res # 处理多个数据 elif type(data) is type([]): with sqlite_db.atomic(): for d in data: # 根据id判断数据是否存在 exist = self.count('id', d['id'], _type=2) # 数据不存在 插入 if exist == 0: self.table.create(**d) res = "INSERT" # 数据存在 更新 else: self.update('id', d['id'], d) res = "UPDATE" return res else: logger.error("待插入的数据有误%s" % (str(data))) return "ERROR"
def jude_request(self, resp): """ :param resp: 请求的原始返回结果 :return: 判断请求是否成功 如果不成功 直接采集相关措施 1. 请求结果判断如果不是有效响应则再次发起请求 2. 有可能需要更新参数 """ resp_json = resp.json() # 正常 向下传递返回结果 if resp_json['errmsg'] == 'ok': self.success = True return resp # 参数过期 重新操作手机获取参数 # elif resp_json['errmsg'] == 'no session': # logger.error('获取历史文章列表 参数过期%s'%(resp_json)) # stop_and_start.check() # 账号被限制 发生在获取列表次数过多的情况下 # elif resp_json['errmsg'] == '': # pass else: self.success = False logger.error('获取历史文章列表参数过期或微信被限制%s'%(resp_json)) return None
def l1l1ll1111_wcplus_(self): """ :return: 取出一个任务 请求html内容 """ global l11ll111l_wcplus_ global nickname task = self.l1l1l1l1ll_wcplus_ if task is None: return else: proxy_ip, index = self.l1ll111l11_wcplus_() l1l11l11l1_wcplus_ = False l1ll11ll11_wcplus_ = None l1l1lll1l1_wcplus_ = False l1lll11l1l_wcplus_ = copy(task['content_url']) while not l1l11l11l1_wcplus_: try: if '127.0.0.1' in proxy_ip['ip']: if 'https' not in task['content_url']: task['content_url'] = task['content_url'].replace( 'http', 'https') r = requests.get(url=task['content_url'], headers=self.headers, timeout=5) else: r = requests.get(url=task['content_url'], headers=self.headers, timeout=5, proxies={ 'http': proxy_ip['ip'], 'https': proxy_ip['ip'] }) l1ll11ll11_wcplus_ = r.text if '访问过于频繁,请用微信扫描二维码进行访问' in l1ll11ll11_wcplus_ or '<title>验证</title>' in l1ll11ll11_wcplus_ or 'IP Address:' in l1ll11ll11_wcplus_: logger.error('IP被限制:' + task['content_url']) l1l1ll1l11_wcplus_.l1ll11111l_wcplus_( proxy_ip['ip'], 'IP被限制') if l1l1ll1l11_wcplus_.l1ll111ll1_wcplus_( proxy_ip['ip']): proxy_ip['ip'] = self.l1l11l1111_wcplus_() l1l1lll1l1_wcplus_ = True else: l1l1llll1l_wcplus_ = l1llllll11_wcplus_.decode_content( l1ll11ll11_wcplus_, l1l11l1l11_wcplus_=True) l1l1llll1l_wcplus_['id'] = encryptString( task['content_url'].replace('https', 'http')) if l1ll11l1ll_wcplus_ == 'true': l1llllll11_wcplus_.l1l11ll111_wcplus_( nickname=nickname, file_name=l1l1llll1l_wcplus_['id'], l1l1l11l11_wcplus_=l1ll11ll11_wcplus_) l11ll111l_wcplus_.insert('id', l1l1llll1l_wcplus_) l1l11l11l1_wcplus_ = True except ProxyError: l1l1lll1l1_wcplus_ = True print(task['id'], proxy_ip, 'ProxyError', task['content_url']) l1l1ll1l11_wcplus_.l1ll11111l_wcplus_( proxy_ip['ip'], 'ProxyError') if l1l1ll1l11_wcplus_.l1ll111ll1_wcplus_(proxy_ip['ip']): proxy_ip['ip'] = self.l1l11l1111_wcplus_() except SSLError: l1l1lll1l1_wcplus_ = True print(task['id'], proxy_ip, 'SSLError') l1l1ll1l11_wcplus_.l1ll11111l_wcplus_( proxy_ip['ip'], 'SSLError') if l1l1ll1l11_wcplus_.l1ll111ll1_wcplus_(proxy_ip['ip']): proxy_ip['ip'] = self.l1l11l1111_wcplus_() except Timeout: l1l1lll1l1_wcplus_ = True print(task['id'], proxy_ip, 'Timeout') l1l1ll1l11_wcplus_.l1ll11111l_wcplus_( proxy_ip['ip'], 'Timeout') if l1l1ll1l11_wcplus_.l1ll111ll1_wcplus_(proxy_ip['ip']): proxy_ip['ip'] = self.l1l11l1111_wcplus_() except ConnectionError: l1l1lll1l1_wcplus_ = True print(task['id'], proxy_ip, 'ConnectionError') l1l1ll1l11_wcplus_.l1ll11111l_wcplus_( proxy_ip['ip'], 'ConnectionError') if l1l1ll1l11_wcplus_.l1ll111ll1_wcplus_(proxy_ip['ip']): proxy_ip['ip'] = self.l1l11l1111_wcplus_() except Exception as e: template = 'An exception of type {0} occurred. Arguments:\n{1!r}' message = template.format(type(e).__name__, e.args) print(message) self.l1l11l111l_wcplus_.task_done() if l1l1lll1l1_wcplus_: self.l1l1l11111_wcplus_(proxy_ip, index) self.l1l11lll1l_wcplus_() l1l1ll1l11_wcplus_.l1ll1l1l1l_wcplus_(proxy_ip['ip']) l1l1ll1l11_wcplus_.l1l1l11lll_wcplus_() return l1ll11ll11_wcplus_