ここではコードである:それは基本的に、使用して、urlllib.request.urlopen、ループ内で再帰的にURLを開くWebクローラーをより効率的にする方法
str_regex = '(https?:\/\/)?([a-z]+\d\.)?([a-z]+\.)?activeingredients\.[a-z]+(/?(work|about|contact)?/?([a-zA-z-]+)*)?/?'
import urllib.request
from Stacks import Stack
import re
import functools
import operator as op
from nary_tree import *
url = 'http://www.activeingredients.com/'
s = set()
List = []
url_list = []
def f_go(List, s, url):
try:
if url in s:
return
s.add(url)
with urllib.request.urlopen(url) as response:
html = response.read()
#print(url)
h = html.decode("utf-8")
lst0 = prepare_expression(list(h))
ntr = buildNaryParseTree(lst0)
lst2 = nary_tree_tolist(ntr)
lst3= functools.reduce(op.add, lst2, [])
str2 = ''.join(lst3)
List.append(str2)
f1 = re.finditer(str_regex, h)
l1 = []
for tok in f1:
ind1 = tok.span()
l1.append(h[ind1[0]:ind1[1]])
for exp in l1:
length = len(l1)
if (exp[-1] == 'g' and exp[length - 2] == 'p' and exp[length - 3] == 'j') or \
(exp[-1] == 'p' and exp[length - 2] == 'n' and exp[length - 3] == 'g'):
pass
else:
f_go(List, s, exp, iter_cnt + 1, url_list)
except:
return
。特定のドメイン(この場合はactiveingredients.com)で動作します。リンク抽出フォームは、正規表現によってページが行われます。内部では、開いているページを持つと、それを解析し、文字列としてリストに追加します。それで、これは、与えられたドメインを通り、情報(その場合は意味のあるテキスト)を抽出し、リストに追加することです。ブロックを除いて試してみてください。すべてのhttpエラー(およびすべての残りのエラーもありますが、これはテスト済みで動作しています)の場合にのみ返されます。
たとえば、この小さなページでは機能しますが、それ以上のものは非常に遅くてメモリを消費します。
ページを解析して、多かれ少なかれ正しい仕事をしていると私は信じています。
質問は、これを行う効率的な方法はありますか?ウェブがネットワークをすばやくクロールする方法
** working code **の場合は、[codereview.se]を参照してください。しかし、なぜあなたは[正規表現でHTMLを解析していますか](http://stackoverflow.com/a/1732454/3001761)? – jonrsharpe
ネットワークのコンテンツを待っている時間が多いので、マルチスレッドは間違いなく使用するはずです。複数の要求を同時に送信する必要があります。 –
これは良い質問ですが、答えは複雑です。まず、データセット全体をメモリにロードする必要がないように、データベースを使用してデータを格納する必要があります。また、複数のWebリクエストを並行してロードする必要があります。しかし、ええ、これは一種の複雑な作業です。おそらくこれを行う既存のライブラリを探してみてください。 – dana