1. 爬虫基础

文章目录

简介

  • 这几篇博客是一个系列,最终目标是能独立编写爬虫项目
  • 技术点包括反爬处理手段、正则表达式使用、抓包技术、模拟请求等,熟练掌握urllib模块,最终还要学习Scrapy框架
  • 当然,也可能会结合其他模块,提升效率必须要有模块化的思想
  • 如果你是小白,想快速感受一下爬虫到底要怎么做,可以看我的github博客

Python基础

  • 这里要用到的Python基础包括
    • 基础语法
    • 函数及模块
    • 文件操作
    • 异常处理
    • 面向对象编程
  • 在我的Python基础专栏有详细介绍,这里就不赘述,但这些东西是必须要会的!

Web基础

  • 爬虫是在爬网页信息(当然也包含APP等),了解基本的网页HTML+CSS代码是必须的
    • 网页分类:
    • 静态网页(包括一些拖管博客)
    • 动态网络
    • WebService(RestAPI)
  • 这部分在我的PythonWeb专栏中有详细介绍,花一天时间即可!

爬虫基础

  • 技术选型
    • 很多人使用request+beautifulsoup,这里主要使用Scrapy,为什么?
      • 前面这俩只是库,而S是框架
      • S中可以加入r/b
      • S基于twisted,是一个异步框架,性能好(gevent了解一下)
      • S方便扩展,也提供了很多内置功能
      • S内置CSS+Xpath Selector(lxml是基于C语言写的,快),beautifulsoup最大的确点是慢!
  • 爬虫作用
    • 搜索引擎
    • 推荐引擎
    • 机器学习样本
    • 数据分析
  • 正则表达式
    • 处理字符串的必备,我的github博客中有详细介绍
    • 把握两个关键点:特殊字符元字符
    import re
    # . 匹配除换行符(\n、\r)之外的任何单个字符
    # * 匹配前面的子表达式零次或多次
    # + 匹配前面的子表达式一次或多次
    
    # 特殊字符:^ $
    string = 'Roooooooooyy is handsome!'
    regex = '^R.*\!$'
    match = re.match(regex, string)
    print(match)	# Roooooooooyy is handsome!
    
    # 特殊字符:?	匹配前面的子表达式零次或一次,或指明一个非贪婪限定符
    regex = '.*(R.*y).*'	
    print(match.group(1))	# Roooooooooyy 贪婪的意思就是从右往左匹配(整个字符串都参与)
    regex = '.*?(R.*?y).*'	# 非贪婪,针对后面的y
    print(match.group(1))	# Roooooooooy	这里的括号是字符串提取模式,配合group
    # ? * +一般都是针对前面字符的
    
    # 特殊字符:{}
    string = 'bbybaaby'
    regex = '.*(b.{3,}y).*'	# 前面的字符出现3次及以上;{2,5}表示2次到5次都可
    print(match.group(1))	# baaby
    regex = '.*(b.{1}y).*'	# bby
    
    # 特殊字符:[]	中括号中的任何一个都可以
    string = 'roy233kun666*'
    regex = '([rst]oy)|([opq]ykun)'
    print(match.group(1))	# roy
    
    regex = '.*([0-9]{3})'	# 输入一个范围,还可以[a-z]
    print(match.group(1))	# 666	这就叫贪婪模式,从后开始!
    
    regex = '.*?([0-9 ^6]{3})'	
    print(match.group(1))	# 233	匹配不是6的数,^这里代表 非
    
    regex = '.*([*])'
    print(match.group(1))	# *  中括号中的特殊字符不再有特殊意义,或者有其他含义
    
    # 元字符:\s  匹配任何空白字符
    # \S	匹配任何非空白字符,等价于 [^\f\n\r\t\v]
    string = 'Hello World'
    regex = '(Hello\sWorld)'	# Hello World
    
    # 元字符:\w	 匹配非字母、数字、下划线,等价于 [^A-Z a-z 0-9 _]
    # 同样,\W 相反
    string = 'aAb157_'
    regex = '\w*'
    print(match)	# aAb157_
    
    # 元字符: \d  匹配数字
    string = '出生日期:2007年'
    regex = '.*?(\d+)'	# 非贪婪,否则只能匹配到7
    # 匹配连续的数字:非贪婪或者用{4}指定,这两种方式
    print(match.group(1))	# 2007
    
    # 提取汉字:\u4E00-\u9FA5
    string = 'roy杨瑞nidaye大爷'
    regex = '.*([\u4E00-\u9FA5]+)'	# 注意,前面的 .* 必须加上
    print(match.group(1))	# 爷
    
    • 如果匹配的字符前有其他字符,必须加上.*,否则无法开始匹配;要通盘考虑!
    • 如果?被当做非贪婪模式,可以理解成从左开始匹配;默认贪婪(非左贪右)
    • regex规则只有一个,为什么提取字串有group(1/2/3…)呢?这是针对一个规则多处匹配,别在pattern并列写多个()
  • 看个实例:提取用户出生日期
    1. 爬虫基础

BFS和DFS

  • 网页结构和URL采用树结构
  • 以伯乐在线网站为例:URL层次设计
    1. 爬虫基础
    • 明白了这一点,可以让我们在系统爬取的时候制定策略:
      1. 爬虫基础
    • 还要注意链接环路,例如每个页面都会加上“首页”,如果按序爬取会出现死循环;此时需要加上爬虫去重
  • 如何爬取上面的URL结构,抽象出来就是如何遍历此树形结构
    • 学过数据结构就知道,树的遍历分两种:深度优先(递归)和广度优先(队列)
    • 深度优先以访问根节点的次序,又包括三种:先序、中序、后序遍历
    • 结构抽象如下:
      1. 爬虫基础
    • 深度优先代码:
      1. 爬虫基础
    • 以上是先序遍历:ABDEICFGH
    • 注意这里递归出口直接 return 调用了,也可以不写子节点的None判断,直接走else:return
    • 广度优先代码:只需要一个队列即可!
      1. 爬虫基础
    • 相当于对应树的层序遍历:ABCDEFGHI
  • 去重策略
    • 将访问过的URL保存到数据库中,获取下一个URL时去查询,看看有没有爬过
      • 显然,效率非常低下,但是最简单!
    • 将访问过的URL保存到内存中
      • 查的快,但吃内存啊!
    • URL经过MD5等方法后保存到set中
      • md5算法的好处是可以将任意长度的字符串压缩到相同的固定长度
      • 数据内容相差很小,其值也有较大差别
      • 原数据计算出md5值很容易
      • 配合上集合set,其特点就是不重复,和Python的字典键值一样
    • 用bitmap方法,将访问过的URL通过hash函数映射到某一位
      • 只要是hash,就必须考虑冲突处理
    • 用bloomfilter方法对bitmap改进,主要是多重hash函数降低冲突
      • 这种用位映射级别的压缩,压的是相当猛的!所以此方法常用
      • 怎么用?后面说!

字符编码

  • 这个问题在Python基础中也说过,这里再次强调
  • Unicode想一统天下,但是存储的时候会多浪费空间,于是出现了utf8可变长编码
  • 英文就用一字节,中文就用三字节,这样在存储或者传输的时候能节省空间提高效率
    • 但是问题来了,长度不一样处理器就不好办了,于是:
      1. 爬虫基础
    • 看个例子:
      1. 爬虫基础
    • 把握一点,encode中会用默认编码decode,但默认的是ASCII编码,所以直接报错!
    • Windows中编码环境为gb2312,Linux编码环境为utf8,但同理,还是要先decode
    • 当然,以上是python2的问题,Python3中用str对象解决了
      • 定义时全部Unicode,如果文件操作需要utf8会提示!咱再整(就上图那个流程)
  • 下面我们开始具体学习使用Scrapy框架

小结

  • 这篇重点回顾了Python和爬虫基础,对技术选型和正则表达式详细介绍
  • 强烈推荐看一下里面链接的文章,很多东西有了基础概念才能相互联系,知识点融会才能提升
上一篇:C#中使用正则表达式校验输入的是否为英文字母 【转载自】


下一篇:正则表达式 Python for Data Analysis 笔记