在python中创建一个新的生成器实例

时间:2016-10-16 05:08:10

标签: python generator yield-keyword

我正在尝试抓取一个页面,其中包含许多指向包含广告的网页的链接。我目前正在进行导航的内容是转到第一页,其中包含广告列表并获取各个广告的链接。之后,我检查以确保我没有通过从数据库中提取数据来删除任何链接。下面的代码基本上获取所有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 个答案:

答案 0 :(得分:0)

如果你把连续页面的逻辑放到生成器函数中,我认为你的代码会更简单。这样可以让你使用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值。要像您的旧代码那样使用限制进行迭代,请在达到限制时使用enumeratebreak

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之前不是一次查找)。也许这就是你想要它做的,但我怀疑用另一种方式做得更快。