0

Web サイトの URL からディレクトリ階層を抽出したいと考えています。すべての Web サイトがディレクトリ構造に準拠しているわけではありません。(以下) を行う Web サイトについては、ディレクトリ階層を反映する Python 辞書 (以下) を作成できるようにしたいと考えています。URL から構造を辞書に抽出できる Python スクリプトを作成するにはどうすればよいですか?

Raw data:
http://www.ex.com
http://www.ex.com/product_cat_1/
http://www.ex.com/product_cat_1/item_1
http://www.ex.com/product_cat_1/item_2
http://www.ex.com/product_cat_2/
http://www.ex.com/product_cat_2/item_1
http://www.ex.com/product_cat_2/item_2
http://www.ex.com/terms_and_conditions/
http://www.ex.com/Media_Center



Example output:
{'url':'http://www.ex.com', 'sub_dir':[
{'url':'http://www.ex.com/product_cat_1/', 'sub_dir':[
                        {'url':'http://www.ex.com/product_cat_1/item_1'}, {'url':'http://www.ex.com/product_cat_1/item_2'}]},
{'url':'http://www.ex.com/product_cat_2/', 'sub_dir':[
                        {'url':'http://www.ex.com/product_cat_2/item_1'},
                        'url':'http://www.ex.com/product_cat_2/item_2']},
{'url':'http://www.ex.com/terms_and_conditions/'},
{'url':'http://www.ex.com/Media_Center'},
]}
4

3 に答える 3

0

これは、わずかに異なる出力形式のソリューションです。まず、sub_dirキーの代わりにurl、ディレクトリ構造をネストされた dict として表すことができます。ここで、空の dict は空のディレクトリまたはファイル (ツリーの葉) です。

たとえば、入力文字列

"www.foo.com/images/hellokitty.jpg"
"www.foo.com/images/t-rex.jpg"
"www.foo.com/videos/" 

次のようなディレクトリ構造をマップします。

{
    "www.foo.com": {
        "images": {
            "hellokitty.jpg": {},
            "t-rex.jpg": {}
        },
        "videos": {}
    }
}

このモデルでは、データ文字列の解析は for ループ、if ステートメント、およびいくつかの文字列関数の単純な組み合わせです。

コード:

raw_data = [
    "http://www.ex.com",
    "http://www.ex.com/product_cat_1/",
    "http://www.ex.com/product_cat_1/item_1",
    "http://www.ex.com/product_cat_1/item_2",
    "http://www.ex.com/product_cat_2/",
    "http://www.ex.com/product_cat_2/item_1",
    "http://www.ex.com/product_cat_2/item_2",
    "http://www.ex.com/terms_and_conditions/",
    "http://www.ex.com/Media_Center"
]

root = {}

for url in raw_data:
    last_dir = root
    for dir_name in url.lstrip("htp:/").rstrip("/").split("/"):
        if dir_name in last_dir:
            last_dir = last_dir[dir_name]
        else:
            last_dir[dir_name] = {}

出力:

{
  "www.ex.com": {
    "Media_Center": {}, 
    "terms_and_conditions": {}, 
    "product_cat_1": {
      "item_2": {}, 
      "item_1": {}
    }, 
    "product_cat_2": {
      "item_2": {}, 
      "item_1": {}
    }
  }
}
于 2013-07-09T23:32:31.397 に答える
0

要求された出力を直接生成するスクリプトを次に示します (注: ファイルから入力を受け取ります。スクリプトの最初の (そして唯一の) コマンド ライン引数としてファイル名を指定します)。注意。ブッチのソリューションを使用してから、おそらくこの形式に変換すると、クリーンで高速になる可能性があります。

#!/usr/bin/env python

from urlparse import urlparse
from itertools import ifilter


def match(init, path):
    return path.startswith(init) and init[-1] == "/"

def add_url(tree, url):
    while True:
        if tree["url"] == url:
            return
        f = list(ifilter(lambda t: match(t["url"], url),
                         tree.get("sub_dir", [])))
        if len(f) > 0:
            tree = f[0]
            continue
        sub = {"url": url}
        tree.setdefault("sub_dir", []).append(sub)
        return

def build_tree(urls):
    urls.sort()
    url0 = urls[0]
    tree = {'url': url0}
    for url in urls[1:]:
        add_url(tree, url)
    return tree

def read_urls(filename):
    urls = []
    with open(filename) as fd:
        for line in fd:
            url = urlparse(line.strip())
            urls.append("".join([url.scheme, "://", url.netloc, url.path]))
    return urls


if __name__ == "__main__":
    import sys
    urls = read_urls(sys.argv[1])
    tree = build_tree(urls)
    print("%r" % tree)
于 2013-07-09T23:53:37.903 に答える
0
For each item:
   if it is a subdir of something else:
       add it to the subdirectory list of that item
   otherwise:
       add it to the main list.
于 2013-07-09T22:54:23.740 に答える