Создать новый экземпляр генератора в python

Я пытаюсь почистить страницу, на которой много ссылок на страницы с рекламой. То, что я сейчас делаю для навигации, - это переход на первую страницу со списком объявлений и получение ссылки на отдельные объявления. После этого я проверяю, чтобы убедиться, что я не удалил ни одну из ссылок, извлекая данные из моей базы данных. Код ниже в основном получает все атрибуты href и объединяет их в виде списка. После этого я проверяю его по списку ссылок, которые я сохранил в своей базе данных страниц, которые я уже просмотрел. Так что в основном он вернет список ссылок, которые я еще не просмотрел.

@staticmethod
def _scrape_home_urls(driver):
    home_url_list = list(home_tab.find_element_by_tag_name('a').get_attribute('href') for home_tab in driver.find_elements_by_css_selector('div[class^="nhs_HomeResItem  clearfix"]'))
    return (home_url for home_url in home_url_list if home_url not in(url[0] for url in NewHomeSource.outputDB()))

Как только он очищает все ссылки на этой странице, он переходит к следующей. Я попытался использовать его снова, вызвав _scrape_home_urls()

    NewHomeSource.unique_home_list = NewHomeSource._scrape_home_urls(driver)
    for x in xrange(0,limit):

        try:
            home_url = NewHomeSource.unique_home_list.next()

        except StopIteration:
            page_num = int(NewHomeSource.current_url[NewHomeSource.current_url.rfind('-')+1:]) + 1 #extract page number from url and gets next page by adding 1. example: /.../.../page-3
            page_url = NewHomeSource.current_url[:NewHomeSource.current_url.rfind('-')+1] + str(page_num)
            print page_url
            driver.get(page_url)
            NewHomeSource.current_url = driver.current_url
            NewHomeSource.unique_home_list = NewHomeSource._scrape_home_urls(driver)
            home_url = NewHomeSource.unique_home_list.next()

            #and then I use the home_url to do some processing within the loop

Заранее спасибо.

1 ответ

Мне кажется, что ваш код будет намного проще, если вы поместите логику, которая очищает последовательные страницы, в функцию генератора. Это позволит вам использовать for петли, а не возиться и звонить next на объектах генератора напрямую:

def urls_gen(driver):
    while True:
        for url in NewHomeSource._scrape_home_urls(driver):
            yield url
        page_num = int(NewHomeSource.current_url[NewHomeSource.current_url.rfind('-')+1:]) + 1 #extract page number from url and gets next page by adding 1. example: /.../.../page-3
        page_url = NewHomeSource.current_url[:NewHomeSource.current_url.rfind('-')+1] + str(page_num)
        print page_url
        driver.get(page_url)
        NewHomeSource.current_url = driver.current_url

Это позволит прозрачно пропустить страницы, на которых нет необработанных ссылок. Функция генератора выдает значения url бесконечно. Чтобы выполнить итерацию с ограничением, как это делал ваш старый код, используйте enumerate а также break когда предел достигнут:

for i, home_url in urls_gen(driver):
    if  i == limit:
        break

    # do stuff with home_url here

Я не изменил ваш код, кроме того, что было необходимо для изменения итерации. Однако есть немало других вещей, которые можно улучшить. Например, используя более короткую переменную, чем NewHomeSource.current_url сделало бы строки этого числа для определения номера страницы, а затем URL следующей страницы намного более компактным и читабельным. Мне также не ясно, где эта переменная изначально установлена. Если он не используется нигде вне этого цикла, его можно легко заменить на локальную переменную в urls_gen,

Ваш _scrape_home_urls функция, вероятно, также очень неэффективна. Похоже, что он выполняет запрос к базе данных для каждого URL-адреса, который он возвращает (не один поиск до проверки всех URL-адресов). Может быть, это то, что вы хотите, чтобы сделать, но я подозреваю, что это было бы гораздо быстрее сделать по-другому.

Другие вопросы по тегам