2017-10-28 130 views
1

我已經寫了一個使用python從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

你return語句過早終止您的get_links()函數。意思是這部分

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) 

永遠不會執行。

Quickfix會將return語句放在函數末尾,但必須使film_storage爲全局(在get_links()函數的外部定義)。

編輯: 剛剛意識到,由於您將使您的film_storage爲全局,因此不需要return語句。

你在主代碼只是看起來像這樣:

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

這似乎很有希望。試一試,讓你知道。謝謝。 – SIM

+0

順便說一句,這只是一個quickfix解決方案,正如你剛纔提到的那樣,你剛剛開始了你的拼搶之旅。但我建議你在將來嘗試@ 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

感謝您的輸入randomir。爲此+1。 – SIM

+0

不客氣,但請注意,你應該儘量避免全局變量。它們使得你的代碼不易讀,**程序的不同部分以意想不到的方式耦合在一起**,並且整體上你的程序更容易出錯。 – randomir