Python中的URL树遍历器?

3
对于像Pypi packages这样显示文件树形结构的URL, 是否有一个小而坚实的模块可以遍历URL树并像ls -lR一样列出它?
我了解到(请纠正我),在html <A属性中没有文件属性,链接类型,大小,日期等的标准编码方式, 因此在不断变化的基础上建立一个坚实的URLtree模块是很困难的。
但是肯定已经有人发明了这个轮子(Unix文件树-> html-> treewalk API-> ls -lR或find)。
(似乎有几个蜘蛛/网络爬虫/刮刀,但是它们看起来很丑陋和特别,尽管使用了漂亮的汤用于解析)。
3个回答

3

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),将其导入本地文件,以列出大的远程文件? - denis
非常请教,任何在事后阅读此内容的人,请记住使用正则表达式解析XML / HTML的经典答案。还有其他几百个答案。在这种特定情况下,Apache目录列表格式“不应该”更改,但我们都知道在软件中“不应该”的含义(尤其是与UI相关的情况)。 - Tim Alexander
没错,一个真正的解析器会是一个更具弹性的解决方案,但是对于基于简单模式匹配或正确语法的爬虫来说,任何清单格式的更改都往往会导致其失效。 - rmmh

1

其他人推荐使用BeautifulSoup,但是使用lxml要好得多。尽管它的名称如此,但它也用于解析和抓取HTML。它比BeautifulSoup快得多。如果您不想学习lxml API,它还具有BeautifulSoup的兼容API。

Ian Blicking同意这一观点

除非您在Google App Engine或其他任何不允许使用纯Python之外的地方,否则没有理由再使用BeautifulSoup了。

它还具有CSS选择器,因此这种事情非常简单。


0
原来像这样的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,但不可能一直解析全部HTML"


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接