美文网首页Python爬虫
python分布式爬虫:爬虫基础知识

python分布式爬虫:爬虫基础知识

作者: 码农小杨 | 来源:发表于2017-05-01 15:22 被阅读62次

    技术选型

    scrapy vs requests + beautifulsoup

    1,requests和beautifulsoup都是库,scrapy是框架
    2,scrapy框架中可以加入requests和beautifulsoup
    3,scrapy基于twisted(异步I/O),性能是最大的优势
    4,scrapy方便扩展,提供了很多内置的功能
    5,scrapy内置的css和xpath selector非常方便,beautifulsoup最大的缺点就是慢(对HTML进行分析)

    网页分类

    常见类型的服务
    1,静态网页(静态博客)
    2,动态网页
    3,webservice(restapi)

    爬虫能做什么

    爬虫作用
    1,搜索引擎--百度,google,垂直领域搜索引擎
    2,推荐引擎--今日头条
    3,机器学习的数据样本
    4,数据分析(如金融数据分析),舆情分析等。

    正则表达式

    目录:
    1,特殊字符

    1. ^ $ * ? + {2} {2,} {2,5} |
    2. [] [^] [a-z] .
    3. \s \S \w \W
    4. [\u4E00-\u9FA5] () \d

    2,正则表达式的简单应用及python示例
    栗子1:

    import  re
    
    line = "bobby123"
    regex_str = "^b.*"
    if re.match(regex_str,line):
        print("yes")
    

    栗子二:

    import  re
    
    line = "boooooooobby123"
    regex_str = ".*?(b.*?b).*"
    mathch_obj = re.match(regex_str,line)
    if mathch_obj:
        print(mathch_obj.group(1))
    

    当没有加 ? 的时候是贪婪匹配(从最后开始匹配),加了之后是非贪婪模式(从前面开始匹配)。

    注意: [ ] 里面的特殊字符不再有特殊含义,[ * ]就是匹配 *

    栗子三:

    import  re
    
    line = "你 好"
    regex_str = "(你\s好)"
    mathch_obj = re.match(regex_str,line)
    if mathch_obj:
        print(mathch_obj.group(1))
    

    栗子四:

    import  re
    
    line = "你好s"
    regex_str = "([\u4E00-\u9FA5]+)"
    mathch_obj = re.match(regex_str,line)
    if mathch_obj:
        print(mathch_obj.group(1))
    

    使用[\u4E00-\u9FA5]可以匹配连续的中文
    我们看下一个字符串中除了中文还有其它字符的时候,我们想提取大学前面和大学

    import  re
    
    line = "study in 南京大学"
    regex_str = ".*?([\u4E00-\u9FA5]+大学)"
    mathch_obj = re.match(regex_str,line)
    if mathch_obj:
        print(mathch_obj.group(1))
    

    深度优先和广度优先

    目录:
    1,网站的树结构
    2,深度优先算法和实现
    3,广度优先算法和实现

    网站url的结构图:伯乐在线

    Paste_Image.png

    网站设计是分层的,多级域名的。

    网站url链接的结构图

    Paste_Image.png

    为了防止循环爬取,对已经爬取过的链接新建一个list存放。在爬取之前,我们进行一次判断,如果没有爬取过,才爬取。

    深度优先图:

    Paste_Image.png

    深度优先:每次爬取到无链接可爬取为止,然后向上层返回查找。
    广度优先:每次爬取当前页面可访问的所有兄弟节点。(分层)
    1,深度优先输出A,B,D,E,I,C,F,G,H(递归实现)
    2,广度优先输出A,B,C,D,E,F,G,H,I(队列实现)

    深度优先过程:

    In [1]: def depth_tree(tree_node):
       ...:     if tree_node is not None:
       ...:         print(tree_node._data)
       ...:         if tree_node._left is not None:
       ...:             return depth_tree(tree_node._left)
       ...:         if tree.node._right is not None:
       ...:             return depth_tree(tree_node._right)
       ...:
    

    注意:递归太深会导致栈溢出

    广度优先过程:

    In [4]: def level_queue(root):
       ...:     """利用队列实现树的广度优先遍历"""
       ...:     if root is None:
       ...:         return
       ...:     my_queue = []
       ...:     node = root
       ...:     my_queue.append(node)
       ...:     while my_queue:
       ...:         node = my_queue.pop(0)
       ...:         print (node.elem)
       ...:         if node.lchild is not None:
       ...:             my_queue.append(node.lchild)
       ...:         if node.rchild is not None:
       ...:             my_queue.append(node.rchild)
       ...:
    

    爬虫去重策略

    1,将访问过的url保存到数据库中
    (每次拿到一个新的url都会去数据库查询是否被爬取过,效率低)
    2,将访问过的url保存到内存set中,只需要O(1)的代价就可以查询url
    假设有一亿个url,占用内存:
    1000000002byte50个字符/1024/1024/1024 = 9G
    3,url经过md5等方法哈希后保存到set
    经过编码之后,可以对数据压缩
    4,用bitmap方法,将访问过的url通过hash函数映射到某一位
    将url映射到byte的位上,但是具有高冲突
    5,bloomfilter方法对bitmap进行改进,多重hash函数降低冲突

    字符串编码

    image.png image.png

    utf8编码在保存和网络传输的时候,使用的空间较小。
    而unicode编码在编程的时候,因为字节统一,便于编程。

    因此文件文件保存的时候,我们保存为utf-8的格式,读取到内存的时候,我们转化为Unicode编码。当由内存保存至文件的时候,我们再将编码改为utf-8的编码格式。

    Paste_Image.png

    获取系统默认编码

    In [1]: import sys
    
    In [2]: sys.getdefaultencoding
    Out[2]: <function sys.getdefaultencoding>
    
    In [3]: sys.getdefaultencoding()
    Out[3]: 'utf-8'
    

    想要encode之前要保证字符串是Unicode格式。

    相关文章

      网友评论

        本文标题:python分布式爬虫:爬虫基础知识

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