刮刀只收集第一页的内容

时间:2017-10-28 10:31:18

标签: python python-3.x web-scraping return

我使用python编写了一个刮刀来刮掉yiffy torrent中的电影名称。该网页已经遍历了大约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)

但是,当我喜欢下面的内容时,我会得到所有结果(仅粘贴gist部分):

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)

2 个答案:

答案 0 :(得分:1)

您的film_storage结果列表是函数get_links() 的本地结果列表,它是递归调用的下一页。在递归调用之后(对于所有下一页),初始(entry)函数仅返回第一页的结果。

你必须要么(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

答案 1 :(得分: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语句。

您在main中的代码看起来像这样:

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