下面是一個代碼:如何使網絡爬蟲更有效?
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
它基本上,使用,urlllib.request.urlopen,遞歸地在一個循環中打開的網址;在某些領域(在這種情況下,activeingredients.com);鏈接提取形式的頁面是通過regexpression完成的。在裏面,打開頁面解析它並以字符串形式添加到列表中。所以,這是假設要做的是通過給定的域,提取信息(在這種情況下有意義的文本),添加到列表。嘗試除了塊,只是在所有http錯誤(以及所有其他錯誤,但這是測試和工作)的情況下返回。
例如,它適用於這個小頁面,但是對於較大的頁面來說非常緩慢並且可以節省內存。
我相信,解析,準備頁面,或多或少都能做正確的工作。
問題是,有沒有一種有效的方法來做到這一點?網絡搜索如何快速抓取網絡?
如果這是**工作代碼**,請參閱[codereview.se]。但是,你爲什麼[用正則表達式解析HTML](http://stackoverflow.com/a/1732454/3001761)? – jonrsharpe
在我看來,你絕對應該使用多線程,因爲大部分時間你都在等待網絡內容。您應該同時發送多個請求。 –
這是一個很好的問題,但答案很複雜。對於初學者,您應該使用數據庫來存儲數據,以便整個數據集不需要加載到內存中。另外,您應該並行加載多個Web請求。但是,這是一項複雜的任務。也許嘗試尋找一個現有的庫,這樣做? – dana