Создать новый экземпляр генератора в 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-адресов). Может быть, это то, что вы хотите, чтобы сделать, но я подозреваю, что это было бы гораздо быстрее сделать по-другому.