美文网首页Python学习程序员
Python 爬虫第三篇(循环爬取多个网页)

Python 爬虫第三篇(循环爬取多个网页)

作者: keinYe | 来源:发表于2019-03-26 12:03 被阅读0次

    本篇是 python 爬虫的第三篇,在前面两篇 Python 爬虫第一篇(urllib+regex)Python 爬虫第二篇(urllib+BeautifulSoup) 中介绍了如何获取给定网址的网页信息,并解析其中的内容。本篇将更进一步,根据给定网址获取并解析给定网址及其相关联网址中的内容。要实现这些功能,我们需要解决以下问题:

    1. 如何持续不断的获取网址,并读取相关内容。
    2. 如何判断网址是否已经读取过。

    文中用到的代码均已上传到 github,在这里就不再贴出完整的代码了。

    如何持续不断的获取网址,并读取相关内容?

    要想读取网页内容,首先要获取网页的 url,但是我们又不能将所有的 url 都输入到程序中,此时就需要我们从已知的 url 中解析出其他的 url,从而不间断的获取新的 url读取新的内容,获取新的 url 可以通过解析含有 href 属性的 a 标签来实现,具体代码如下:

    for link in html.find_all(name='a', href=re.compile(r'https?://list|item.szlcsc.+')):
        if len(self.__url_set) > self.__max_url_count:
            return
        url = link.get('href')
    

    以上代码解析出所有的 a 标签中的 href 属性内容以 https://list.szlcschttps://item.szlcsc 为开头的 url 连接。在这里还是设置了一个最大的 url 解析量「由于在测试中需要一个停止条件」,默认值为1000。

    从一个 url 中获取到更多的 url 后,我们该怎么去读取?以什么顺序去读取?不可能获取一个 url 就读取一个 url,此时就需要一个保存 url 的地方「最好是可以顺序保存顺序取出的」,那么最好的方法就是使用队列了,以下是将 url 放入队列的代码:

    for link in html.find_all(name='a', href=re.compile(r'https?://list|item.szlcsc.+')):
        if len(self.__url_set) > self.__max_url_count:
            return
        url = link.get('href')
        if url not in self.__url_set:
            self.__url_set.add(url)
            self.__url_queue.put(url)
    

    以下是从队列中取出 url 的代码:

    while not self.__url_queue.empty():
        count = count + 1
        url = self.__url_queue.get()
        result = self.get_html(url)
    

    以上两段代码完成了一个 url 从存入队列到从队列中出的全过程。

    如何判断网址是否已经读取过?

    这个问题实际上就是 url 去重的问题,常用的 url 去重的方法主要有以下几种:

    1. url保存在数据库中(效率低)
    2. 将 url 保存到集合中,利用集合的无重复元素的特性来去重,缺点是占用空间大。
    3. 将 url 通过 md5 等哈希算法后保存到集合中去重,可以大幅度提高内容利用率。
    4. 使用布隆过滤器「Bloom Filter」,在时间和空间方面有巨大的优势,但是存在一定的误算率,不适用于高准确度的场合。

    本篇我们使用集合来对 url 进行去重,其他方法大家可以自行搜索一下,网上有很多这方面的资料。

    集合中的元素无次序,且不可重复。元素不可重复的特性用来对 url 去重在合适不过了,通过判断 url 是否已经在集合中可以快速判断该 url 是否已经读取过。具体看以下代码:

    if url not in self.__url_set:
        self.__url_set.add(url)
        self.__url_queue.put(url)
    

    以上代码首先判断 url 是否存在于 __url_set 中,如果不存在则将该 url 添加到 __url_set 中,同时将次 url 放入读取队列中进行读取。这样既对得到的每个 url 进行读取,又避免了多次读取同一个 url 造成资源的浪费。

    相关文章

      网友评论

        本文标题:Python 爬虫第三篇(循环爬取多个网页)

        本文链接:https://www.haomeiwen.com/subject/ycuivqtx.html