2016-10-16 4 views
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 

미리 감사드립니다.

+0

나는 당신이 무엇을 요구하고 있는지 잘 모르겠습니다. 표시하는 코드가 올바르게 작동하지 않습니까? 그렇다면 어떻게? 예외가 발생 했습니까 아니면 올바른 결과를 산출하지 못하고 있습니까? 아니면 효과가 있습니까?하지만 어떤면에서는 더 좋을 수 있다고 생각하십니까? 귀하의 질문이 무엇인지에 대해 구체적으로 말씀해주십시오. 귀하의 코드와 해당 내용에 대한 설명만으로는 충분하지 않습니다. – Blckknght

+0

죄송합니다. 코드가 작동하지 않습니다. 마지막 코드 블록의 마지막 줄에서 StopIteration 예외가 발생합니다. – h3y4w

답변

0

연속적인 페이지를 생성기 함수로 긁어 모으는 로직을 넣으면 코드가 훨씬 더 단순 해 보입니다. 이 객체를 직접 오히려 장난 및 발전기에 next를 호출하는 것보다 for 루프를 사용 할 것 :이 투명하게 처리되지 않은 링크가없는 페이지를 건너 것

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을 확인하기 전에 하나의 조회가 아닙니다). 어쩌면 그것이 당신이 원하는 것일 수도 있지만, 다른 방법으로는 훨씬 더 빠를 것이라고 생각합니다.

+0

피드백을 보내 주셔서 감사합니다. 제안을 포함시켜야합니다. NewHomeSource의 var current_url은 for 루프 앞에 설정되어 사용됩니다. 또한 데이터베이스 쿼리의 경우 더 효율적으로 만들려면 무엇을 제안 하시겠습니까? 나는 150 개가 넘는 행을 가지지 않기로 계획하고 있으며, 현재는 한 번에 모든 쿼리를 수행하고 있습니다. 행은 URL을 보유하고있는 link라는 레이블이 붙은 한 개의 열만 있습니다 (아마 추측했을 것입니다). – h3y4w

관련 문제