网络爬虫的过程:
什么是URL 统一资源定位符是对可以从互联网得到的资源的位置和访问方法的一种简介的表示,是互联网上标准资源的地址。互联网上的每一个文件都有一个唯一的URL,它包含的信息指出文件的位置以及浏览器应该怎样处理它。
所有的URL去重都是在内存上进行的——>可提速
举个例子:
Hash算法是检测一个元素是否存在的高效算法。对于一个输入,我们只需要计算其散列值,并在这个散列值对应的桶中查找元素是否存在就行了,不需要遍历所有所有元素。如在上图中,要检测数字88是否存在,只需要检测88号桶中是否存在数字88即可。
问题:
解决方法:
开放寻址:所有的元素经过Hash映射后都存放在散列表中
拉链法:将Hash散列表看作一个链表数组。数组中的位置要么为空,要么指向散列到该位置的链表
拉链法的实现过程:
拉链法的优点 优点:
两者对比:
Python
的数据类型—集合,来保存已经爬取过的URL
import requests,re
count = 3
r = re.compile(r'href=[\'"]?(http[^\'">]+)')
seed = 'http://httpbin.org/'
queue = [seed]
used = set() # 设置一个集合,保存已经抓取过的URL
storage = {}
Python
语言的set
:
eg:
while len(queue) > 0 and count > 0 :
try:
url = queue.pop(0)
html = requests.get(url).text
storage[url] = html #将已经抓取过的URL存入used集合中
used.add(url)
new_urls = r.findall(html) # 将新发行未抓取的URL添加到queue中
for new_url in new_urls:
if new_url not in used and new_url not in queue:
queue.append(new_url)
count -= 1
except Exception as e :
print(url)
print(e)
from collections import Counter
url_count = Counter(queue)
for url,count in url_count.most_common(10):
print(url,count)
所得结果如下图:
import requests,re
import time
from collections import Counter
count = 3
recount = 0
allcount = 1
r = re.compile(r'href=[\'"]?(http[^\'">]+)')
seed = 'http://httpbin.org/'
queue = [seed]
used = set() # 设置一个集合,保存已经抓取过的URL
storage = {}
while len(queue) > 0 and count > 0 :
try:
url = queue.pop(0)
html = requests.get(url).text
storage[url] = html #将已经抓取过的URL存入used集合中
used.add(url)
new_urls = r.findall(html) # 将新发行未抓取的URL添加到queue中
for new_url in new_urls:
allcount += 1
if new_url not in used and new_url not in queue:
queue.append(new_url)
else:
print("重复:"+url)
recount += 1
count -= 1
except Exception as e :
print(url)
print(e)
print("重复网站:"+str(recount))
print("总网站:"+str(allcount))
url_count = Counter(queue)
for url,count in url_count.most_common(10):
print(url,count)
去重的重要性: 因为网站结构的关系,它会进行重复的引用。
总结:
使用第三方库hashlib来实现MD5映射算法
import hashlib
src1 = 'https://baidu.com'
m1 = hashlib.md5()
m1.update(src1.encode('utf-8'))
print(m1.hexdigest())
src2 = 'https://baidu.com'
m2 = hashlib.md5()
m2.update(src2.encode('utf-8'))
print(m2.hexdigest())
Bloom Filter是在1970年代由Bloom出的一种多哈希函数映射的快速查找算法
它是一种空间效率高的随机数据结构
Bloom Filter的基本思路是:通过多个不同的Hash函数来解决“冲突”
Bloom Filter主要包含以下两个部分:
Bloom Filter的任务是,判断URL是否已经抓取过
在下图中,有三个hash函数。假设x,y,z是已经抓取过的URL
w是要判断的URL:
Bloom Filter的查询时间和空间效率虽高,但是有以下缺点:
Python中有很多Bloom Filter的开源实现,我们这里选用pybloom工具包
pybloom的主要类和函数有:
创建一个Bloom Filter:
import pybloom_live
f = pybloom_live.BloomFilter(capacity = 1000,error_rate = 0.001)
[f.add(x) for x in range(10)]
重定向(redirect)允许一个网页在不同的域名下显示
重定向有两种形式:
客户端重定向是在服务器将页面内容发送到浏览器之前,由浏览器执行JavaScript完成的页面跳转,而不是服务器完成的跳转
当浏览器访问页面的时候,有时很难区分这两种重定向:
客户端重定向,也成为HTTP重定向,是HTTP协议规定的一种机制。
重定向的机制如下图:
服务器重定向是在处理客户端提交的request过程中,服务器将request先后委托多个处理单元接替进行处理的过程
Python
的urllib
库解决,不需要使用Selenium
JavaScript
重定向的类型有很多种,301和302是最常见的两种
当网页A用301重定向转到网页B时,搜索殷勤肯定网页A永久的改变位置,或者说实际上不存在,搜索引擎就会把网页B当作唯一有效目标
这样做的好处: