def filter_price(self, apt='', id=''): try: # 매매 for size, prices in self.prices.items(): avg_price = round(sum(prices) / len(prices)) notice = '' # 전일 데이터가 있다면 비교 후 메세지에 포함 if str(size) in self.prices_filter: yesterday_price = self.prices_filter[str(size)][1] minus = avg_price - yesterday_price increase = round((minus) / yesterday_price * 100, 1) updown = '' if increase > 0: updown = '증가' elif increase < 0: updown = '감소' if updown: notice += '%s[%s] %d만원 (%.1f%%) %s \n' % ( apt, size, minus, increase, updown) self.prices_filter[size] = [ min(prices), avg_price, max(prices) ] # 급매알리미 if self.prices_filter[size][1] * 0.9 > self.prices_filter[ size][0]: sale_percent = self.prices_filter[size][ 0] / self.prices_filter[size][1] * 100 uniqid = '%s%s%d' % (id, size, self.prices_filter[size][0]) if uniqid not in self.log: message = '%s[%s] %d만원 (평균대비 %d%% 저렴)' % ( apt, size, self.prices_filter[size][0], math.ceil(sale_percent)) self.log = filewriter.slice_json_by_max_len( self.log, max_len=100) self.send_messge_and_save(uniqid, message, 'yoona_azzi') # 전세 for size, prices in self.jeonses.items(): avg_price = round(sum(prices) / len(prices)) self.jeonses_filter[size] = [ min(prices), avg_price, max(prices) ] # 증감메세지 발송 if notice: telegrambot.send_message(notice, 'yoona_azzi') except Exception as e: log.logger.error(e, exc_info=True) return False
def scan_page(self): try: if self.selenium_extract_by_xpath(tag={ 'tag': 'div', 'attr': 'class', 'name': 'evt-item-lst' }) is False: raise Exception('selenium_extract_by_xpath fail.') soup = BeautifulSoup(self.driver.page_source, 'html.parser') element = soup.find('div', class_="evt-item-lst") # 1+1 영화 리스트 if element: for list in element.children: if not list == -1: linkObj = list.find('a') imgObj = list.find('img') if not linkObj == -1: title = imgObj['alt'] # 수집 성공로그 self.record_success_log() if "1+1" not in title: continue link = linkObj['href'] img = imgObj['src'] m = re.search('idx=(.*?)\&', link) id = m.group(1) link = self.DETAIL_URL + link.replace('./', '') if id and id not in self.log: shop = '핫딜사이트: CGV' title = '상품명: %s' % title ppomppuLinkGenerator = PpomppuLinkGenerator() link = ppomppuLinkGenerator.getShortener( url=link) link = '구매 바로가기: %s' % link text = shop + '\n' + title + '\n' + link # print(text) # self.destroy() # exit() self.log = filewriter.slice_json_by_max_len( self.log, max_len=100) self.send_messge_and_save(id, text, 'hotdeal') except Exception as e: log.logger.error(e, exc_info=True)
def scan_page(self): try: if self.selenium_extract_by_xpath(tag={ 'tag': 'ul', 'attr': 'class', 'name': 'emovie_list' }) is False: self.remove_proxy_server_ip_list() raise Exception('selenium_extract_by_xpath fail.') soup = BeautifulSoup(self.driver.page_source, 'html.parser') element = soup.find('ul', class_='emovie_list') # 1+1 영화 리스트 if element: for list in element.find_all('li'): link_tag = list.find('a') attr_click = link_tag['onclick'].strip() id = re.search(r'ilsMove\(\"(.*?)\",', attr_click).group(1) if id and id not in self.log: title = link_tag.find('img')['alt'].strip() # 수집 성공로그 self.record_success_log() if "1+1" not in title: continue shop = '핫딜사이트: 롯데시네마' date = list.find( 'p', class_='evt_period').getText().strip() #price = list.find('span', class_='price').getText() title = '상품명: %s (%s)' % (title, date) ppomppuLinkGenerator = PpomppuLinkGenerator() img = link_tag.find('img')['src'].strip() link = self.DETAIL_URL + id link = ppomppuLinkGenerator.getShortener(url=link) link = '구매 바로가기: %s' % link text = shop + '\n' + title + '\n' + link + '\n' + img # print(text) # self.destroy() # exit() self.log = filewriter.slice_json_by_max_len( self.log, max_len=100) self.send_messge_and_save(id, text, 'hotdeal') except Exception as e: self.destroy() log.logger.error(e, exc_info=True)
def set_log(self, apt=''): try: self.data[apt][self.today] = { 'total_prices_complete': self.total_prices_complete, 'total_jeonses_complete': self.total_jeonses_complete, 'total_prices': self.total_prices, 'total_jeonses': self.total_jeonses, 'prices': self.prices_filter, 'jeonses': self.jeonses_filter, } self.data[apt] = filewriter.slice_json_by_max_len(self.data[apt], max_len=100) log.logger.info('%s collecting done.' % (apt)) except Exception as e: log.logger.error(e, exc_info=True)
def scan_page(self): try: if self.selenium_extract_by_xpath(tag={ 'tag': 'table', 'attr': 'id', 'name': 'revolution_main_table' }) is False: raise Exception('selenium_extract_by_xpath fail.') soup = BeautifulSoup(self.driver.page_source, 'html.parser') element = soup.find('table', id='revolution_main_table') # 핫딜리스트 if element: for list in element.find_all('tr', class_=re.compile('list[0-9]')): try: tds = list.find_all('td', recursive=False) title = tds[3].find('font').getText().strip() good = int( tds[5].getText().strip().split('-')[0].strip()) regdate = tds[4]['title'].strip() s2 = tds[4].getText().strip() s1 = datetime.now( timezone('Asia/Seoul')).strftime('%H:%M:%S') tdelta = datetime.strptime( s1, '%H:%M:%S') - datetime.strptime( s2, '%H:%M:%S') hours, remainder = divmod(tdelta.seconds, 3600) minutes, seconds = divmod(remainder, 60) # 수집 성공로그 self.record_success_log() if regdate and regdate not in self.log and good and good >= self.BASE_GOOD: if good < self.MAX_GOOD: if hours > 0 or minutes > 10: continue link = self.DETAIL_URL + tds[3].find( 'a')['href'].strip() status = '★☆☆☆☆' try: if hours < 4: status = '★★☆☆☆' if hours < 2: status = '★★★☆☆' if hours < 1: status = '★★★★☆' if minutes < 20: status = '★★★★★' if minutes < 10: status = '★★★★★★' #timelap = 'time lap: %d hour %d minutes before' % (hours, minutes) #timelap = '등록시간: %d시간 %d분 전' % (hours, minutes) timelap = '핫딜점수: %s' % status except Exception as errorMessage: status = '★☆☆☆☆' try: indexShop = title.index(']') shop = '핫딜사이트: %s' % title[1:indexShop].strip() title = '상품명: %s' % title[indexShop + 1:].strip() except Exception as errorMessage: title = '상품명: %s' % title ppomppuLinkGenerator = PpomppuLinkGenerator() boardLink = ppomppuLinkGenerator.getShortener( url=link) boardLink = '게시글 바로가기: %s' % boardLink text = title + '\n' + timelap + '\n' + shop + '\n' + boardLink # 어필리에이트 링크 생성 ailliateLink = self.get_item_link(link) if ailliateLink is not False and len( ailliateLink) > 0: text += '\n상품 바로가기: ' + ailliateLink text = text + '\n\n * 이미지를 클릭해 상세내용을 확인하세요.' # print(text) # self.destroy() # exit() self.log = filewriter.slice_json_by_max_len( self.log, max_len=100) self.send_messge_and_save(regdate, text, 'hotdeal') except Exception as e: continue except Exception as e: log.logger.error(e, exc_info=True)
def scan_page(self): try: sleep(5) self.remove_layer() # 신규주문 페이지로 이동 if self.selenium_click_by_xpath(tag={ 'tag': 'a', 'attr': 'data-nclicks-code', 'name': 'orddel.new' }) is False: raise Exception('selenium_click_by_xpath fail. orddel.new') sleep(10) self.remove_layer() # 주문 데이터 가져오기 iframe으로 변경 self.driver.switch_to.frame( frame_reference=self.driver.find_element_by_xpath( '//iframe[@id="__naverpay"]')) list_id = self.driver.find_element_by_xpath( '//*[@id="__app_root__"]/div/div[2]/div[3]/div[4]/div[1]/div[2]/div[1]/div[1]/div[2]/div/div[1]/table' ).find_elements_by_xpath('.//tbody/tr') list = self.driver.find_element_by_xpath( '//*[@id="__app_root__"]/div/div[2]/div[3]/div[4]/div[1]/div[2]/div[1]/div[2]/div[2]/div/div[1]/table' ).find_elements_by_xpath('.//tbody/tr') # self.driver.switch_to.frame(frame_reference=self.driver.find_element_by_xpath('//iframe[@id="__naverpay"]')) # list = self.driver.find_element_by_xpath('//*[@id="gridbox"]/div[2]/div[2]/table').find_elements_by_xpath('.//tbody/tr') window_before = self.driver.window_handles[0] # for index, li in enumerate(list): # try: # if li: # soup_order_info = BeautifulSoup(li.get_attribute('innerHTML'), 'html.parser') # tds = soup_order_info.find_all('td') # # if tds: # item_order_id = tds[1].getText().strip() # order_id = tds[2].getText().strip() # item_id = tds[17].getText().strip() # item_name = tds[18].getText().strip() # item_kind = tds[19].getText().strip() # item_option = tds[20].getText().strip() # item_amount = tds[22].getText().strip() # destination = tds[44].getText().strip() for i, li in enumerate(list): try: if li: soup_order_info_id = BeautifulSoup( list_id[i].get_attribute('innerHTML'), 'html.parser') tds_id = soup_order_info_id.find_all('td') soup_order_info = BeautifulSoup( li.get_attribute('innerHTML'), 'html.parser') tds = soup_order_info.find_all('td') if tds: item_order_id = tds_id[1].getText().strip() buyer = tds[8].getText().strip() item_id = tds[13].getText() item_name = tds[14].getText() item_kind = tds[15].getText() item_option = tds[16].getText().strip() item_amount = tds[18].getText().strip() destination = tds[40].getText() # print(item_order_id) # print(item_id) # print(item_option) # print(item_amount) # print(item_kind) # print(item_name) # print(buyer) # exit() # 테스트 # if buyer != '서미숙': # continue # 수동 발송제한 # 2019-06-10 샴푸브러쉬 품절 # if item_id in ['4423398036']: # continue # 추가상품 발송제한 if item_kind == '추가구성상품': continue # 발송내역에 없는지 확인 if not item_order_id or item_order_id in self.log: continue if item_option: item_name = item_name + ' (' + item_option + ')' if item_amount: item_name = item_name + ' ' + item_amount + '개' talktalklink = li.find_element_by_xpath( './/td[6]/div/a') # talktalklink = li.find_element_by_xpath('.//td[10]/a') # 톡톡하기 클릭 talktalklink.click() sleep(3) # 톡톡창으로 focus window_after = self.driver.window_handles[1] self.driver.switch_to.window(window_after) # 레이어가 있다면 닫기 try: if self.selenium_exist_by_xpath( xpath= '//button[contains(@class,"btn_negative")]' ) is True: self.selenium_click_by_xpath( xpath= '//button[contains(@class,"btn_negative")]' ) except: pass # 메세지 생성 message = self.get_delevery_message( item_id=item_id, item_name=item_name, destination=destination) if not message: raise Exception('messageText genarating fail.') # 메시지 입력 self.driver.execute_script( 'document.getElementById("partner_chat_write").value = "' + message + '";') if self.selenium_input_text_by_xpath( text=' ', xpath='//*[@id="partner_chat_write"]', clear=False) is False: raise Exception( 'selenium_input_text_by_xpath fail. chat_write' ) # exit() sleep(1) # 메세지 전송 if self.selenium_click_by_xpath( xpath= '//*[@id="chat_wrap"]/div/div[1]/div/div[3]/div[2]/button' ) is False: raise Exception( 'selenium_click_by_xpath fail. submit') sleep(2) message = message.replace('\\n', '\n') self.log = filewriter.slice_json_by_max_len( self.log, max_len=1000) self.send_messge_and_save(item_order_id, message, 'kuhit') # telegrambot.send_message(message, 'kuhit') # 창 닫고 복귀 self.driver.close() self.driver.switch_to.window(window_before) self.driver.switch_to.frame( frame_reference=self.driver. find_element_by_xpath( '//iframe[@id="__naverpay"]')) # 테스트로그 # print(buyer) # print(item_order_id) # print(item_id) # print(item_name) # print(destination) # print(tds) # for idx, td in enumerate(tds): # print(idx, td.getText()) except Exception as e: log.logger.error(e, exc_info=True) self.destroy() exit() return True except Exception as e: self.driver.save_screenshot('smartstore_screenshot.png') log.logger.error(e, exc_info=True) self.destroy() exit() return False
def scan_page(self): try: sleep(5) # 레이어가 있다면 닫기 (에스크로, 임시) try: if self.selenium_exist_by_xpath(xpath='/html/body/div[1]/div/div/div[3]/div/div/label') is True: self.selenium_click_by_xpath(xpath='/html/body/div[1]/div/div/div[3]/div/div/label') except: pass try: if self.selenium_exist_by_xpath(xpath='/html/body/div[1]/div/div/div[3]/div/div/label/input') is True: self.selenium_click_by_xpath(xpath='/html/body/div[1]/div/div/div[3]/div/div/label/input') except: pass # 레이어가 있다면 닫기 try: if self.selenium_exist_by_xpath(tag={'tag': 'button', 'attr': 'data-dismiss', 'name': 'mySmallModalLabel'}) is True: self.selenium_click_by_xpath(tag={'tag': 'button', 'attr': 'data-dismiss', 'name': 'mySmallModalLabel'}) except: pass # 문의체크 (2020-01-10) try: ask = self.driver.find_elements_by_xpath('//*[@name="inquery"]/div/div[2]/ul/li') if ask: is_ask = False for ask_li in ask: ask_number = ask_li.find_element_by_xpath('.//p[@class="text-number"]').text ask_number = int(ask_number) if ask_number > 0: is_ask = True if is_ask == True: telegrambot.send_message('정성한끼 고객이 상담을 기다리고 있습니다.', 'jshk') except: pass # 문의까지만. self.destroy() exit() # 신규주문 페이지로 이동 if self.selenium_click_by_xpath(tag={'tag': 'a', 'attr': 'data-nclicks-code', 'name': 'orddel.new'}) is False: raise Exception('selenium_click_by_xpath fail. submit') # if self.selenium_click_by_xpath(tag={'tag': 'a', 'attr': 'data-nclicks-code', 'name': 'orddel.wait'}) is False: # raise Exception('selenium_click_by_xpath fail. submit') sleep(10) # 레이어가 있다면 닫기 try: if self.selenium_exist_by_xpath(tag={'tag': 'button', 'attr': 'data-dismiss', 'name': 'mySmallModalLabel'}) is True: self.selenium_click_by_xpath(tag={'tag': 'button', 'attr': 'data-dismiss', 'name': 'mySmallModalLabel'}) except: pass # 주문 데이터 가져오기 iframe으로 변경 self.driver.switch_to.frame(frame_reference=self.driver.find_element_by_xpath('//iframe[@id="__naverpay"]')) list = self.driver.find_element_by_xpath('//*[@id="gridbox"]/div[2]/div[2]/table').find_elements_by_xpath('.//tbody/tr') window_before = self.driver.window_handles[0] prev_order_id = None no_messages = {} for index, li in enumerate(list): try: if li: soup_order_info = BeautifulSoup(li.get_attribute('innerHTML'), 'html.parser') tds = soup_order_info.find_all('td') if tds: order_id = tds[2].getText().strip() item_name = tds[18].getText() item_kind = tds[19].getText() item_option = tds[20].getText().strip() item_amount = tds[22].getText().strip() item_id = tds[17].getText() destination = tds[44].getText() # 추가상품 발송제한 if item_kind == '추가구성상품': continue # 발송내역에 없는지 확인 if not order_id or order_id in self.log: continue # *요일조리후발송 옵션인 경우 메세지에서 제외 if '조리후발송' in item_option: no_messages[order_id] = True # 다음 주문이 같은 주문번호라면 continue try: if (list[index + 1]): soup_order_info_next = BeautifulSoup(list[index + 1].get_attribute('innerHTML'), 'html.parser') tds_next = soup_order_info_next.find_all('td') order_id_next = tds_next[2].getText().strip() if order_id == order_id_next: continue except: pass try: # 메세지제외인 주문번호인 경우 제외 if no_messages[order_id]: continue except: pass if item_option: item_name = item_name + ' (' + item_option + ')' if item_amount: item_name = item_name + ' ' + item_amount + '개' # print(item_option) # print(item_amount) # print(item_kind) # print(item_name) # print(buyer) # exit() talktalklink = li.find_element_by_xpath('.//td[10]/a') # 톡톡하기 클릭 talktalklink.click() sleep(3) # 톡톡창으로 focus window_after = self.driver.window_handles[1] self.driver.switch_to.window(window_after) # 레이어가 있다면 닫기 try: if self.selenium_exist_by_xpath(xpath='//button[contains(@class,"btn_negative")]') is True: self.selenium_click_by_xpath(xpath='//button[contains(@class,"btn_negative")]') except: pass # 메세지 생성 message = self.get_delevery_message(item_id=item_id, item_name=item_name, destination=destination) if not message: raise Exception('messageText genarating fail.') # 메시지 입력 self.driver.execute_script('document.getElementById("partner_chat_write").value = "' + message + '";') if self.selenium_input_text_by_xpath(text=' ', xpath='//*[@id="partner_chat_write"]', clear=False) is False: raise Exception('selenium_input_text_by_xpath fail. chat_write') sleep(1) # 메세지 전송 if self.selenium_click_by_xpath(xpath='//*[@id="chat_wrap"]/div/div[1]/div/div[3]/div[2]/button') is False: raise Exception('selenium_click_by_xpath fail. submit') sleep(2) message = message.replace('\\n', '\n') self.log = filewriter.slice_json_by_max_len(self.log, max_len=1000) self.send_messge_and_save(order_id, message, 'jshk') # 창 닫고 복귀 self.driver.close() self.driver.switch_to.window(window_before) self.driver.switch_to.frame(frame_reference=self.driver.find_element_by_xpath('//iframe[@id="__naverpay"]')) # 테스트로그 # print(buyer) # print(order_id) # print(item_id) # print(item_name) # print(destination) # print(tds) # for idx, td in enumerate(tds): # print(idx, td.getText()) except Exception as e: log.logger.error(e, exc_info=True) self.destroy() exit() return True except Exception as e: log.logger.error(e, exc_info=True) self.destroy() exit() return False