首页 Python爬虫1.2 - URL管理器
文章
取消

Python爬虫1.2 - URL管理器

URL管理器的实现

新建一个python软件包文件夹,名为utils,意为一些常用的工具,并在该文件夹下新建一个名为url_manager的python脚本。

输入以下代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
class Url_Manager():
    """
    URL管理器的实现
    """

    def __init__(self):
        self.new_urls = set()
        self.old_urls = set()

    def add_new_url(self, url):
        if url is None or len(url) == 0:
            return
        if url in self.new_urls or url in self.old_urls:
            return
        self.new_urls.add(url)

    def add_new_urls(self, urls):
        if urls is None or len(urls) == 0:
            return
        for url in urls:
            self.add_new_url(url)

    def get_url(self):
        if self.has_new_url():
            new_url = self.new_urls.pop()
            self.old_urls.add(new_url)
            return new_url
        else:
            return None

    def has_new_url(self):
        return len(self.new_urls) > 0


if __name__ == "__main__":
    url_manager = Url_Manager()
    url_manager.add_new_url("http://www.baidu.com")
    url_manager.add_new_url("http://www.sina.com")
    print(url_manager.new_urls, url_manager.old_urls)

    print("#"*30)
    print(url_manager.has_new_url())

    print("#" * 30)
    print(url_manager.get_url())

    print("#" * 30)
    print(url_manager.get_url())

    print("#" * 30)
    print(url_manager.get_url())

    print("#" * 30)
    print(url_manager.has_new_url())
    
    print("#" * 30)
    print(url_manager.new_urls, url_manager.old_urls)

简单解释一下各个函数的功能:

1
2
3
def __init__(self):
    self.new_urls = set()  # 待爬取URL
    self.old_urls = set()  # 已爬取URL

这个函数是Python类的初始化构造函数,我们这里为这个类创建两个新的set容器,分别用于已爬取和未爬取的URL。


1
2
3
4
5
6
def add_new_url(self, url):
    if url is None or len(url) == 0:
        return
    if url in self.new_urls or url in self.old_urls:
        return
    self.new_urls.add(url)

这个函数是新增一条URL。但是注意,我们为了实现防止重复爬取、循环爬取,需要对新来的URL进行判断,看看它是否在待爬取或已爬取的URL的集合中。


1
2
3
4
5
def add_new_urls(self, urls):
    if urls is None or len(urls) == 0:
        return
    for url in urls:
        self.add_new_url(url)

这个函数是新增多条URL。其实现是使用for-each循环遍历urls里面的所有URL,并一条一条调用add_new_url()的方法,这样提高了代码的复用性。


1
2
def has_new_url(self):
    return len(self.new_urls) > 0

这个函数是用于判断是否还有未爬取的URL,只需判断待爬取URL集合的长度是否大于0即可。该函数返回一个布尔变量。


1
2
3
4
5
6
7
def get_url(self):
    if self.has_new_url():
        new_url = self.new_urls.pop()
        self.old_urls.add(new_url)
        return new_url
    else:
        return None

这个函数是取出一条URL,但是在此之前我们需要先判定待爬取的URL中不为空,我们才能取出一条返回。取出后,我们要在待爬取URL的集合中删去这个URL,并将其添加到已爬取URL的集合中。


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
if __name__ == "__main__":
    url_manager = Url_Manager()
    url_manager.add_new_url("http://www.baidu.com")
    url_manager.add_new_url("http://www.sina.com")
    print(url_manager.new_urls, url_manager.old_urls)

    print("#"*30)
    print(url_manager.has_new_url())

    print("#" * 30)
    print(url_manager.get_url())

    print("#" * 30)
    print(url_manager.get_url())

    print("#" * 30)
    print(url_manager.get_url())

    print("#" * 30)
    print(url_manager.has_new_url())
    
    print("#" * 30)
    print(url_manager.new_urls, url_manager.old_urls)

最后段代码是测试用例,仅在该文件(url_manager.py)是作为主程序入口时才运行的一段程序。输出结果如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
{'http://www.baidu.com', 'http://www.sina.com'} set()
##############################
True
##############################
http://www.baidu.com
##############################
http://www.sina.com
##############################
None
##############################
False
##############################
set() {'http://www.baidu.com', 'http://www.sina.com'}

可以看到,执行两次get_url()方法后,我们两条待爬取的URL都被移动到已爬取URL集合中。

本文由作者按照 CC BY 4.0 进行授权