【问题标题】:Opening Multiple Pages with Mechanize in Python在 Python 中使用机械化打开多个页面
【发布时间】:2011-12-04 21:01:31
【问题描述】:

我正在尝试使用 mechanize 以某种格式打开多个页面。我想从某个页面开始,并让机械化跟踪链接中具有特定类别或文本的所有链接。例如,根 url 类似于

http://hansard.millbanksystems.com/offices/prime-minister

并且我想关注页面上具有诸如

格式的每个链接
<li class='office-holder'><a href="http://hansard.millbanksystems.com/people/mr-tony-blair">Mr Tony Blair</a> May  2, 1997 - June 27, 2007</li>

换句话说,我想关注每个具有“office-holder”类或 URL 中具有 /people/ 的链接。我尝试了以下代码,但没有成功。

import mechanize

br = mechanize.Browser()
response = br.open("http://hansard.millbanksystems.com/offices/prime-minister")
links = br.links(url_regex="/people/")

print links

我正在尝试打印链接,以便在编写更多代码之前确保获得正确的链接/信息。我从中得到的错误(?)是:

<generator object _filter_links at 0x10121e6e0>

感谢任何指针或提示。

【问题讨论】:

    标签: python web-scraping mechanize


    【解决方案1】:

    这不是错误 - 这意味着 Browser.links() 返回一个生成器对象而不是一个列表。

    iterator 是一个“类似于列表”的对象,这意味着您可以执行以下操作

    for link in links:
        print link
    

    等等。但是您只能以它定义的任何顺序访问事物;你不一定能做到link[5],一旦你通过了迭代器,它就用完了。

    在大多数情况下,生成器只是一个迭代器,不一定事先知道其所有结果。这在generator expressions 中非常有用,您实际上可以编写非常简单的函数,使用yield 关键字返回生成器:

    def odds():
        x = 1
        while True:
            yield x
            x += 2
    
     os = odds()
     os.next() # returns 1
     os.next() # returns 3
    

    这是一件好事,因为这意味着您不必一次将所有数据存储在内存中(这对于 odds() 来说是不可能的......),如果您只需要前几个元素您不必费心计算其余的结果。 itertools module 有很多方便的函数来处理迭代器。


    无论如何,如果你只是想打印出links 的内容,你可以使用list() 函数将其变成一个列表(它接受一个可迭代对象并返回其元素的列表):

     print list(links)
    

    或使用列表推导创建一个字符串列表:

     print [l.url for l in list(links)]
    

    或者遍历它的元素并将它们打印出来:

     for l in links:
          print l.url
    

    但请注意,在您执行此操作后,links 将“筋疲力尽” - 因此,如果您真的想用它做任何事情,您需要再次获得它。

    也许最简单的选择是立即将它变成一个列表,而根本不用担心它是一个迭代器:

    links = list(br.links(url_regex="/people/"))
    

    此外,您显然还没有获得具有所需课程的链接。这里可能有一些 mechanize 技巧来做一个“或”,但是使用集合和生成器表达式的一个很好的方法是这样的:

     links = set(l.url for l in br.links(url_regex='/people/'))
     links.update(l.url for l in br.get_links_with_class('office-holder'))
    

    显然将get_links_with_class 替换为获取这些链接的真实方法。然后,您将得到一组在其 URL 中具有 /people/ 和/或具有类 office-holder 的所有链接 URL,并且没有重复。 (请注意,您不能将 Link 对象直接放入集合中,因为它们不可散列。)

    【讨论】:

      猜你喜欢
      • 2023-03-10
      • 2013-09-08
      • 2014-09-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多