Использовать выход одной функции в качестве входа другой функции

поэтому я хочу проверить веб-сайт, чтобы обновить меня всякий раз, когда появляется новый элемент. Они не обновляются часто, поэтому я уверен, что, когда они обновят, это будет предметом интереса. Я хочу достичь этого, выбрав «начальное число» и подсчитав количество ссылок на странице, затем сравните это число с количеством ссылок каждые 10 минут, пока количество ссылок не превысит начальное число.

Сначала я запускаю это, чтобы получить «начальный номер» ссылок:

links=[]
for link in soup.findAll('a'):
    links.append(link.get('href'))
start_num = len(links)

Затем сравните это число с количеством ссылок прямо сейчас и каждые 5 секунд:

notify=True
while notify:
    try: 
        page = urllib.request.urlopen('web/site/url')
        soup = bs(page, "lxml")  

        links=[]
        for link in soup.findAll('a'):
            links.append(link.get('href'))

        if len(links) > start_num:
            message = client.messages.create(to="", from_="",body="") 
            print('notified')
            notify=False
        else:
            print('keep going')
            time.sleep(60*5)

    except:
        print("Going to sleep")
        time.sleep(60*10) 

Как я могу объединить все это в 1 функцию, где я могу хранить начальное количество ссылок без перезаписи каждый раз, когда я проверяю его против текущего количества ссылок?

2 ответа

  1. сделать это можно как минимум двумя способами: декораторами и генераторами

    Декораторы:

    def hang_on(func):
    
        # soup should be in a visible scope
        def count_links():
            # refresh page?
            return len(soup.findAll('a'))
    
        start_num = count_links()
    
        def wrapper(*args, **kwargs):
            while True:
                try:
                    new_links = count_links()
                    if  new_links > start_num:
                        start_num = new_links
                        return fund(*args, **kwargs)
                    print('keep going')
                    time.sleep(60*5)            
                except:
                    print("Going to sleep")
                    time.sleep(60*10)         
    
        return wrapper
    
    @hang_on    
    def notify():
        message = client.messages.create(to="", from_="",body="") 
        print('notified')
    
    # somewhere in your code, simply:
    notify()
    

    Генераторы:

    def gen_example(soup):
    
        # initialize soup (perhaps from url)
    
        # soup should be in a visible scope
        def count_links():
            # refresh page?
            return len(soup.findAll('a'))
    
        start_num = count_links()
    
        while True:
            try:
                new_links = count_links()
                if  new_links > start_num:
                    start_num = new_links
                    message = client.messages.create(to="", from_="",body="") 
                    print('notified')
                    yield True  # this is what makes this func a generator
    
                print('keep going')
                time.sleep(60*5)            
            except:
                print("Going to sleep")
                time.sleep(60*10)       
    
    # somewhere in your code:
    gen = gen_example(soup)  # initialize
    
    gen.next()  # will wait and notify
    
    # coming soon
    
  2. Я бы реализовал его как класс, потому что этот код достаточно удобочитаем и прост в поддержке. Наслаждаться:

    class Notifier:
        url = 'web/site/url'
        timeout = 60 * 10
    
        def __links_count(self):
            page = urllib.request.urlopen(self.url)
            soup = bs(page, "lxml")
    
            links=[]
            for link in soup.findAll('a'):
                links.append(link.get('href'))
    
            return len(links)
    
        def __notify(self):
            client.messages.create(to="", from_="", body="")
            print('notified')
    
        def run(self):
            current_count = self.__links_count()
    
            while True:
                try:
                    new_count = self.__links_count()
    
                    if new_count > current_count:
                        self.__notify()
                        break
    
                    sleep(self.timeout)
    
                except:
                    print('Keep going')
                    sleep(self.timeout)
    
    notifier = Norifier()
    notifier.run()