これは、再帰関数を使用して行うことができます。
ページ内にあるすべてのURLを1つずつクロールし、そのページにあるすべてのURLを1つずつクロールするなどの基本的な例...また、見つかったすべてのURLを表示します。
def recursive_fetch(url_to_fetch):
# get page source from url_to_fetch
# make a new soup
for link in soup.find_all('a'):
url = link.get('href')
print url
# run the function recursively
# for the current url
recursive_fetch(url)
# Usage
recursive_fetch(root_url)
あなたが見つかったすべてのURLの木の辞書を持っていると思いますので、上記のコードはあまり有用ではありませんが、それはスタートです。
これは本当に複雑なところです。今あなたはまた、クロールされている現在のURLの親、そのURLの親、そのURLの親、そのURLの親、の親を追跡する必要があるので...
あなたは、私は何を参照してください平均?非常に複雑で非常に高速になります。
以下はすべてのことを行うコードです。私は可能な限り最高の説明をするためにコードにコメントを書いた。しかし、再帰関数がどのようにしてより良い理解のために働くかを実際に理解する必要があります。
まずは、木から、URLの親を取得するには非常に参考になります別の関数を見てみましょう:
def get_parent(tree, parent_list):
"""How it works:
Let's say the `tree` looks like this:
tree = {
'root-url': {
'link-1': {
'link-1-a': {...}
}
}
}
and `parent_list` looks like this:
parent_list = ['root-url', 'link-1', 'link-1-a']
this function will chain the values in the list and
perform a dict lookup like this:
tree['root-url']['link-1']['link-1-a']
"""
first, rest = parent_list[0], parent_list[1:]
try:
if tree[first] and rest:
# if tree or rest aren't empty
# run the function recursively
return get_parent(tree[first], rest)
else:
return tree[first]
except KeyError:
# this is required for creating the
# root_url dict in the tree
# because it doesn't exist yet
tree[first] = {}
return tree[first]
そしてrecursive_fetch
関数は次のようになります。
url_tree = {} # dict to store the url tree
def recursive_fetch(fetch_url, parents=None):
"""
`parents` is a list of parents of the current url
Example:
parents = ['root-url', 'link-1', ... 'parent-link']
"""
parents = parents or []
parents.append(fetch_url)
# get page source from fetch_url
# make new soup object
for link in soup.find_all('a'):
url = link.get('href')
if parents:
parent = get_parent(url_tree, parents)
else:
parent = None
if parent is not None:
# this will run when parent is not None
# i.e. even if parent is empty dict {}
# create a new dict of the current url
# inside the parent dict
parent[url] = {}
else:
# this url has no parent,
# insert this directly in the url_tree
url_tree[url] = {}
# now crawl the current url
recursive_fetch(url, parents)
# Next is the most import block of code
# Whenever 1 recursion completes,
# it will pop the last parent from
# the `parents` list so that in the
# next recursion, the parents are correct.
# Whithout this block, the url_tree wouldn't
# look as expected.
# It took me many hours to figure this out
try:
parents.pop(-1)
except IndexError:
pass
これをまさに私が探しているものです!もともと、Webページに再帰関数を使用することを考えていましたが、どうやってURLを追跡するかわかりませんでした。私はこの[投稿](https://stackoverflow.com/questions/19937210/dynamically-set-deep-python-dict)を見ましたが、それを私のプログラムに跳躍させる方法についてはわかりませんでした。ご協力いただきありがとうございます! – SheepyBloke