0

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

提前致谢。

4

1 回答 1

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 之前不是一次查找)。也许这就是您想要它做的事情,但我怀疑以另一种方式完成会快得多。

于 2016-10-16T06:14:23.650 回答