下面是一个代码:如何使网络爬虫更有效?
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