2017-10-28 1 views
1

저는 파이썬을 사용하여 yiffy 급류에서 영화 이름을 긁어 모으기 위해 작성했습니다. 웹 페이지는 약 12 ​​페이지를 넘었습니다. print 문을 사용하여 크롤러를 실행하면 모든 페이지의 모든 결과가 표시됩니다. 그러나, return을 사용하여 동일하게 실행하면 첫 번째 페이지의 콘텐츠 만 제공되고 나머지 페이지는 다음 페이지로 이동하지 않습니다. return 문의 동작을 이해하는 데 어려움을 겪고 있기 때문에 누군가 내가 잘못 가고있는 부분을 지적하고 해결 방법을 제공하면 매우 행복 할 것입니다. 미리 감사드립니다. 내가 아래와 같이 할 때, 나는 모든 결과 (붙여 넣기 요점 부분 만) 얻을첫 번째 페이지의 내용 만 수집하는 스크레이퍼

import requests 
from urllib.request import urljoin 
from lxml.html import fromstring    

main_link = "https://www.yify-torrent.org/search/western/" 

# film_storage = [] #I tried like this as well (keeping the list storage outside the function) 

def get_links(link): 
    root = fromstring(requests.get(link).text) 
    film_storage = [] 
    for item in root.cssselect(".mv"): 
     name = item.cssselect("h3 a")[0].text 
     film_storage.append(name) 
    return film_storage 

    next_page = root.cssselect(".pager a:contains('Next')")[0].attrib['href'] if root.cssselect(".pager a:contains('Next')") else "" 
    if next_page: 
     full_link = urljoin(link,next_page) 
     get_links(full_link) 

if __name__ == '__main__': 
    items = get_links(main_link) 
    for item in items: 
     print(item) 

하지만, :

def get_links(link): 
    root = fromstring(requests.get(link).text) 
    for item in root.cssselect(".mv"): 
     name = item.cssselect("h3 a")[0].text 
     print(name)   ## using print i get all the results from all the pages 

    next_page = root.cssselect(".pager a:contains('Next')")[0].attrib['href'] if root.cssselect(".pager a:contains('Next')") else "" 
    if next_page: 
     full_link = urljoin(link,next_page) 
     get_links(full_link) 

내가 (전체 코드)에 노력하고있어입니다

답변

1

수익 문은 조기에 당신의 get_links() 함수를 종료합니다. 이 부분의 의미

이 절대로 실행되지 않습니다.

Quickfix는 함수의 끝 부분에 return 문을 넣는 것이지만 get_links() 함수 외부에서 정의 된 전역 film_storage를 만들어야합니다.

편집 : film_storage를 전역으로 만들 예정이므로 return 문이 필요하지 않습니다. 주에서

코드는 그냥 다음과 같을 것이다 : 입력 randomir에 대한

get_links(main_link) 
for item in film_storage: 
    print(item) 
+0

이것은 유망한 것 같습니다. 시도 해보고 알려주세요. 감사. – SIM

+0

Btw, 이것은 단지 퀵 픽스 해결책 일뿐입니다. 그러나 나는 당신이 @ randomir의 해결책/제안을 장래에 시도 할 것을 제안한다. 그렇게하면 더 효율적이고 효율적으로 스크레이퍼를 만들 수 있습니다. – jabargas

+0

죄송합니다. film_storage가 전역이므로 return 문이 필요하지 않습니다. – jabargas

1

film_storage 결과 목록은 다음 페이지에 대해 재귀 적으로 호출되는 get_links() 로컬의 입니다. 재귀 호출 (모든 다음 페이지) 후에 초기 (입력) 함수는 첫 번째 페이지에 대해서만 결과를 반환합니다.

(1) 꼬리 재귀를 루프로 풀지 말고, (2) 결과 목록을 전역으로 만들어야합니다. (3) 콜백 (예 : print)을 사용하거나 가장 좋은 옵션 (4)을 으로 설정하면 get_links 함수를 모든 페이지에 대한 결과를 생성하는 생성기로 바꿀 수 있습니다.

발전기 버전 :

def get_links(link): 
    root = fromstring(requests.get(link).text) 
    for item in root.cssselect(".mv"): 
     name = item.cssselect("h3 a")[0].text 
     yield name 

    next_page = root.cssselect(".pager a:contains('Next')")[0].attrib['href'] if root.cssselect(".pager a:contains('Next')") else "" 
    if next_page: 
     full_link = urljoin(link,next_page) 
     for name in get_links(full_link): 
      yield name 
+0

감사합니다. +1. – SIM

+0

여러분은 환영합니다,하지만 정말로 전역 변수를 피하려고 노력해야합니다. 그들은 당신의 코드를 덜 읽을 수있게합니다 ** 프로그램의 다른 부분은 예기치 않은 방식으로 결합됩니다 **. 그리고 전반적으로 프로그램은 훨씬 오류가 발생하기 쉽습니다. – randomir

관련 문제