在这个系列文章中,你将学习如何完成一个简单的搜索引擎,以及当有人想要用关键词的搜索你的博客网页时,如何响应查询。
你还将学习网络和互联网是如何工作的,进一步了解如何建立一个你自己的搜索索引。
百度、谷歌这些大型搜索引擎虽然很复杂,但是背后的原理和思想是一样的,所以你也可以知道为什么你输入一个关键词,这些搜索引擎就能给你一串页面答案。
贯穿整个系列的主要计算机科学新思想是:如何建立复杂的数据结构。
你将学习如何设计一个你自己就能搭建的数据结构,这样你就可以在你的爬取的网页里响应查询,而不需要在每次都重新扫描所有的网页。你将为此建立的结构就是索引(Index)。
索引的目标是映射一个关键字和该关键字的位置。例如,在一本书的索引中,你可以看到一个页码,它可以作为一个映射,在哪里可以找到一个术语或概念。
索引中的关键概念会让我们找到我们想要的参考资料。
对于搜索引擎来说,索引为你提供了一个关键词映射到网页列表的方法,也就是这些特定关键词出现的URL。
一旦你完成了建立索引的工作,那么查找的速度真的很快。
决定数据结构是构建软件最重要的部分之一。只要你选对了数据结构,剩下的代码就会容易写很多。我们通过下面这个例题来深入了解一下:
在这些数据结构中,哪种数据结构是表示你的搜索引擎的索引的好方法?
.
.
.
.
.
答案揭晓:最好的选择是d,b紧随其后。选择a和c会非常困难。
下面我来解释一下是为什么:
a -很难阅读,因为所有的东西都在一个列表里。这种结构也会使关键词难以循环。
b -这个选项还可以,但不如d。b的结构是这样的,有一个列表,列表中的每个元素都是一个列表,元素列表本身就是列表。这种结构最大的好处是很容易从urls中分辨出关键词,关键词永远是列表的第一个元素。也更容易去看关键词,因为对于每个列表,你只需要看第一个元素,检查是否是你要找的关键词,如果不是,就继续看下一个。这种结构唯一的缺点是,关键词和urls之间的区别可以更加清晰。
c -虽然这有更多的结构,但它并不能使它很容易地查找关键字出现的页面。要查找一个特定的关键字,你必须在每个条目中查找,在条目的第二部分中查找,扫描它,看看关键字是否出现,如果出现了,那么你希望在你的结果中出现网址,如果没有,那么该网址不在结果中。这个选项不是最好的,因为你必须扫描所有的页面,这将花费太多时间。
d -在这种结构中,内部列表中只有两个元素;关键字后面是一个urls列表。这是最好的选择,因为它将关键字和URL列表非常清晰地分开。这也意味着,如果你决定要跟踪其他东西,比如有人搜索每个关键词的次数,你可以通过添加一个额外的元素来轻松实现。这在选项的结构中是比较难做到的。
1. 添加至索引
定义一个操作步骤,add_to_index,它需要三个输入:
- 一个索引(an index) : [[,[,...]],...]
- 一个关键字字符串(a keyword string)
- 一个url字符串(a url string)
如果关键字已经在索引中,将url添加到与该关键字相关联的url列表中。
如果关键字不在索引中,则在索引中添加一个条目:[keyword, [url]]
例如:
index = []add_to_index(index, 'ximalaya', 'http://ximalaya.com')add_to_index(index, 'computing', 'http://acm.org')
这段代码以空列表索引开始。在两行代码之后,空列表将包含两个以关键字开头的列表,ximalaya和computing。
index = []add_to_index(index, 'ximalaya', 'http://ximalaya.com')add_to_index(index, 'computing', 'http://acm.org')add_to_index(index, 'ximalaya', 'http://npr.org')
在这段代码中,ximalaya已经在索引中,你不想在索引本身中添加新的条目。由于ximalaya已经在索引中,你要做的是将新的url添加到已经与该关键字相关联的列表中。
这里是一个数据结构的图像,你正在写一个操作流程:
def add_to_index(index, keyword, url): for entry in index: # 循环遍历index的元素 each one the name entry if entry [0] == keyword: # 检验位置的值是否为0 of entry identical to the keyword that's passed in entry[1].append(url) # 如果它是相等的,把它添加进去 url to the list of urls associated with that entry return # 停止循环 #未找到,增加新的条目
如果没有找到关键字,你要添加一个新的条目,新条目的值是一个包含两个元素的列表,一个是关键字,另一个是包含找到该关键字的urls的列表。
新条目的值将是一个包含两个元素的列表,关键字和第二个元素将是一个包含找到的具有该关键字的urls的列表。到目前为止,只有一个url被传递给index。要做到这一点,请在代码中添加:
def add_to_index(index, keyword, url): for entry in index:if entry [0] == keyword: entry[1].append(url) return # 停止循环index.append([keyword, [url]])
让我们测试一下这个过程,从索引的空列表开始:
index = []add_to_index('ximalaya', 'http://ximalaya.com')print indexTraceback (most recent call last):File "input/test.py", line 11, in add_to_index('ximalaya', 'http://ximalaya.com') TypeError: add_to_index() takes exactly 3 arguments (2 given)
根据错误信息,你必须传入三个参数,index、keyword和url。所以,请继续在里面添加index:
index = []add_to_index(index, 'ximalaya', 'http://ximalaya.com')print index[['ximalaya', ['http://ximalaya.com']]]
试试下一个:
index = []add_to_index(index, 'ximalaya', 'http://ximalaya.com') add_to_index(index, 'computing', 'http://acm.org')print index[['ximalaya', ['http://ximalaya.com']], ['computing', [http://acm.org']]]
现在,试着给一个已经存在的关键词添加一个新的url:
index = []add_to_index(index, 'ximalaya', 'http://ximalaya.com') add_to_index(index, 'computing', 'http://acm.org') add_to_index(index, 'ximalaya', 'http://npr.org')print index[['ximalaya', ['http://ximalaya.com', 'http://npr.org']], ['computing',[http://acm.org']]]
2. 查询流程
定义一个过程,即查找,它需要两个输入:
- 一个索引:一个列表,其中每个元素都是一个包含关键字的列表, 和一个列表作为第二个元素。第二个列表元素是一个包含该关键字的urls列表。
- 要查找的关键字
输出的应该是与关键字相关联的urls的列表。如果关键字不在索引中,输出应该是一个空列表。例如:
lookup('ximalaya') → ['http://ximalaya.com', 'http://npr.org']
def lookup(index, word): # 两个参数 for entry in index: # 对索引进行循环 if entry [0] == keyword: return entry [1] # 如果找到了,则返回相关的URLs with that entry return [] # 如果没有找到关键词,则返回空列表。
在解释器中试试这个:
def lookup(index, word): for entry in index: if entry [0] == keyword: return entry [1]return []index = []add_to_index(index, 'ximalaya', 'http://ximalaya.com') add_to_index(index, 'computing', 'http://acm.org') add_to_index(index, 'ximalaya', 'http://npr.org')print lookup(index, 'ximalaya')['http://ximalaya.com', 'http://npr.org']
试着找一些不在列表中的东西:
print lookup(index, 'audacity')[]
这就是这篇文章的所有内容,寻找页面的URL链接。
爬虫就是根据每个页面的URL链接,然后来爬取整个网站的,了解这一点非常重要。
关注我们,从零到一的开始自学。也可以给我们留言,大胆说出你想要做什么,我们来帮你实现。