2017-10-28 79 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