【问题标题】:URL tree walker in Python?Python中的URL树遍历器?
【发布时间】:2010-10-15 17:29:18
【问题描述】:

对于显示文件树的 URL,例如 Pypi packages, 是否有一个小的实体模块来遍历 URL 树并像 ls -lR 一样列出它?
我收集(纠正我)文件属性没有标准编码, 链接类型、大小、日期...在 html 中 <A 属性
所以在流沙上构建一个可靠的 URLtree 模块是很困难的。
但肯定是这个轮子 (Unix file tree -> html -> treewalk API -> ls -lR or find) 完成了吗?
(那里似乎有几个蜘蛛/网络爬虫/刮板,但到目前为止它们看起来很丑陋且临时,尽管使用 BeautifulSoup 进行解析)。

【问题讨论】:

    标签: python tree beautifulsoup directory-walk


    【解决方案1】:

    Apache 服务器很常见,它们有一个比较标准的列出文件目录的方式。

    这是一个足够简单的脚本,可以做你想做的事,你应该能够让它做你想做的事。

    用法:python list_apache_dir.py

    import sys
    import urllib
    import re
    
    parse_re = re.compile('href="([^"]*)".*(..-...-.... ..:..).*?(\d+[^\s<]*|-)')
              # look for          a link    +  a timestamp  + a size ('-' for dir)
    def list_apache_dir(url):
        try:
            html = urllib.urlopen(url).read()
        except IOError, e:
            print 'error fetching %s: %s' % (url, e)
            return
        if not url.endswith('/'):
            url += '/'
        files = parse_re.findall(html)
        dirs = []
        print url + ' :' 
        print '%4d file' % len(files) + 's' * (len(files) != 1)
        for name, date, size in files:
            if size.strip() == '-':
                size = 'dir'
            if name.endswith('/'):
                dirs += [name]
            print '%5s  %s  %s' % (size, date, name)
    
        for dir in dirs:
            print
            list_apache_dir(url + dir)
    
    for url in sys.argv[1:]:
        print
        list_apache_dir(url) 
    

    【讨论】:

    • 谢谢 sysrqb,很好。这可能是从哪里学到的?另外,有没有什么方法可以在服务器上运行 $(unzip -l remote.zip),通过管道传输到本地文件,以列出大型远程文件?
    • 拜托,任何事后阅读本文的人请记住this classic answer to parsing XML/HTML with regex。还有其他几百人。在这种特殊情况下,apache 目录列表格式不应该改变,但我们都知道“不应该”在软件中的含义(尤其是与 UI 相关的)...
    • 没错,真正的解析器会是一个更有弹性的解决方案,但是对列表格式的任何更改都会破坏刮板——无论是基于简单的模式匹配还是正确的语法。
    【解决方案2】:

    事实证明,像这样的 BeautifulSoup 单行程序可以将

    行转换为 Python --
    from BeautifulSoup import BeautifulSoup
    
    def trow_cols( trow ):
        """ soup.table( "tr" ) -> <td> strings like
            [None, u'Name', u'Last modified', u'Size', u'Description'] 
        """ 
        return [td.next.string for td in trow( "td" )]
    
    def trow_headers( trow ):
        """ soup.table( "tr" ) -> <th> table header strings like
            [None, u'Achoo-1.0-py2.5.egg', u'11-Aug-2008 07:40  ', u'8.9K'] 
        """ 
        return [th.next.string for th in trow( "th" )]
    
    if __name__ == "__main__":
        ...
        soup = BeautifulSoup( html )
        if soup.table:
            trows = soup.table( "tr" )
            print "headers:", trow_headers( trows[0] )
            for row in trows[1:]:
                print trow_cols( row )
    

    与上面 sysrqb 的单行正则表达式相比,这...更长; 谁说的

    "可以解析部分的html全部 时间,或者所有的html一些 时间,但不是……”

    【讨论】:

      【解决方案3】:

      其他人推荐了 BeautifulSoup,但使用 lxml 会更好。尽管它的名字,它也用于解析和抓取 HTML。它比 BeautifulSoup 快得多。如果你不想学习 lxml API,它也有一个 BeautifulSoup 的兼容性 API。

      Ian Blicking agrees.

      没有理由再使用 BeautifulSoup,除非您使用的是 Google App Engine 或不允许使用任何非纯 Python 的东西。

      它也有 CSS 选择器,所以这种事情是微不足道的。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多