【问题标题】:Issue with parsing list of HTML with lxml and requests使用 lxml 和请求解析 HTML 列表的问题
【发布时间】:2014-05-17 05:19:59
【问题描述】:

我有一个存储在变量 href 中的 URL 列表。当我通过下面的函数传递它时,唯一返回的 recipe_links 来自href 中的第一个 URL。我的代码有什么明显的错误吗?我不确定为什么它不会遍历我存储在href 中的所有 20 个 URL。我为href 中的第一个 URL 获得的返回结果按预期检索,但我无法获取到下一个 URL 的循环。

def first_page_links(link):
    recipe_links = []
    recipe_html = []

    for x in link: 
        page_request = requests.get(x)
        recipe_html.append(html.fromstring(page_request.text))

        print recipe_html

        for x in recipe_html:
            recipe_links.append(x.xpath('//*[@id="content"]/ul/li/a/@href'))

            return recipe_links

【问题讨论】:

    标签: python html html-parsing lxml python-requests


    【解决方案1】:

    注意return 的放置位置。您可能希望在所有循环完成后返回:

    def first_page_links(link):
        recipe_links = []
        recipe_html = []
    
        for x in link: 
            page_request = requests.get(x)
            recipe_html.append(html.fromstring(page_request.text))
    
            print recipe_html
    
            for x in recipe_html:
                recipe_links.append(x.xpath('//*[@id="content"]/ul/li/a/@href'))
    
        return recipe_links
    

    【讨论】:

    • 所以我刚刚尝试了这个,我得到了大量的重复结果。
    • @Barnaby:是否也可以将 html 编辑到您的帖子中?
    • 食谱链接是这样进来的:['recipe1', 'recipe1', 'recipe2', 'recipe1', 'recipe2', 'recipe3', 'recipe1', 'recipe2', 'recipe3', 'recipe4', 'recipe1', 'recipe2', 'recipe3', 'recipe4', recipe5'....]
    • 由于某种原因我看不到 HTML,它显示为 [<Element html at 0x10fc88418>] [<Element html at 0x10fc88418>, <Element html at 0x10fc5a368>] [<Element html at 0x10fc88418>, <Element html at 0x10fc5a368>, <Element html at 0x112aaf998>] [<Element html at 0x10fc88418>, <Element html at 0x10fc5a368>, <Element html at 0x112aaf998>, <Element html at 0x112ab9d60>] [<Element html at 0x10fc88418>, <Element html at 0x10fc5a368>, <Element html at 0x112aaf998>, <Element html at 0x112ab9d60>, <Element html at 0x112e0c100>] 这就是为什么我认为我得到了食谱链接的上述输出
    • 发布您要抓取的 URL 怎么样?另外,如果有帮助,请检查我的答案。
    【解决方案2】:

    尝试推出您的第二个循环和您的 return 行,这样就不会发生冗余迭代并正确返回最终列表,如下所示:

    from lxml import html
    import requests as rq
    
    def first_page_links(links):
    
        recipe_links = []
        recipe_html = []
    
        for link in links:
            r = rq.get(link)
            recipe_html.append(html.fromstring(r.text))
    
        for rhtml in recipe_html:
            recipe_links.append(rhtml.xpath('//*[@id="content"]/ul/li/a/@href'))
    
        return recipe_links
    

    让我们知道这是否可行。

    编辑:

    考虑以下几点:

    y_list = []
    final_list = []
    for x in x_list:
        y_list.append(x)
        for y in y_list:
            final_list.append(y)
    

    这是你的函数,简化了。假设在x_list 中有 3 个 URL,会发生以下情况:

    1. x1 附加到 y_list
    2. 到目前为止,y_list 仅使用 x1 处理,因此仅将 x1 附加到 final_listfinal_list 现在包含:[x1]
    3. x2 附加到 y_list
    4. y_list 现在包含 x1x2两者都被处理并附加到final_listfinal_list 现在包含:[x1, x1, x2]
    5. x3 附加到 y_listy_list 现在包含 x1x2x3
    6. 看看这是怎么回事? :)

    由于您的第二个循环处理第一个列表中的项目,它位于第一个循环内,它将递增添加到第一个列表中,第二个循环将处理您的第一个列表第一个循环的每次迭代。这使其成为冗余迭代。

    有很多方法可以执行您想要执行的操作,但如果您只是追加到列表并且需要在两者上进行一次循环,则只需上述修复即可。

    【讨论】:

    • 这完全符合我的要求!谢谢!你能解释一下为什么我让它创建冗余迭代的方式吗?
    • 非常感谢您的详尽解释。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-23
    • 2012-08-23
    • 1970-01-01
    • 2016-04-25
    • 2010-12-07
    • 2011-04-03
    相关资源
    最近更新 更多