Python_爬虫
爬虫对我来说一直是听说过没做过,今天一时兴起将爬虫的课程过了一遍,整理笔记如下。Python中是提供了爬虫库的,但学习中多采用requests库用于理解爬虫的过程。这里仅对老师讲解的部分进行了记录,还有很多未曾接触了,例如动态代理、header模拟浏览器等等针对反爬虫的策略。权当一份框架型笔记即可。
爬虫的主要流程
- 请求获得对应网络信息
- 解析网络信息
- 存储需要的网络信息
Requests库介绍
用于爬虫第一步,发送HTTP请求获取对应网络信息。这里仅对Requests库做整体的介绍,具体方法的操作与技巧,可看[官方文档][https://requests.readthedocs.io/en/master/]或其他相关资料。
requests主要方法
方法 | 说明 | 与HTTP对应 | HTTP说明 |
---|---|---|---|
requests.request() | 基础方法,构造一个请求 | 无 | 无 |
get() | 获取HTML网页内容 | GET | 获得网页全内容 |
head() | 获取HTML网页头信息 | HEAD | 仅获得网页头信息 |
post() | 向HTML网页提交POST请求 | POST | 在已有资源后添加POST资源 |
put() | 向HTML网页提交PUT请求 | PUT | 利用PUT资源替换原有资源 |
patch() | 向HTML网页提交PATCH请求 | PATCH | 局部更新PATCH指定资源 |
delete() | 向HTML网页提交DELETE请求 | DELETE | 删除资源 |
我们可以看到其拥有七个主要方法,并且除基础方法外均一一对应与HTTP定义。除request() 方法外,六个方法均包装了request() 方法,所以上面七个方法本质上均为request() 方法,仅为方便用户使用。
在爬虫应用中,常使用get()或head()方法,其他对于资源修改的方法,反而不常用。
这里需要简单了解HTTP协议,以便更好的理解上述内容。
HTTP协议
HTTP:Hypertext Transfer Protocol , 超文本传输协议,是一种基于”请求与响应“,无状态的应用层协议。
理解此协议可以从定义出发:1.请求与响应:说明HTTP协议的工作方式为客户端向服务器发送请求,服务器向客户端响应。2.无状态:说明HTTP协议前后无关,没有记忆信息。3.应用层:高层协议,已经是面向用户的协议了。
HTTP协议通过URL定位资源,通过对应请求(GET\HEAD\PUT…)进行相关操作。对于URL的格式这里不解释。对于请求,HTTP规定了6种请求方式,如图:
各种方法解释,图上都有,这里不详细解释。我们发现与request的请求方法是一一对应的。前两种方法用于获取数据,后四种方法用于修改数据。
Request对象与Response对象
requests库主要包含两个对象,分别是Request与Response,分别对应发送对象,返回对象。
Response对象属性
属性 | 说明 |
---|---|
r.status_code | HTTP请求的返回状态,200表示连接成功,404表示失败 |
r.text | HTTP相应内容的字符串信息,即URL对应的网页内容 |
r.encoding | 从HTTPheader中猜测的相应内容编码方式 |
r.apparent_encoding | 从内容中分析出的响应内容编码方式 |
r.content | HTTP响应内容的二进制形式 |
注意点:
encoding属性与apparent_encoding的区别
encoding属性是根据HTTP头信息中是否存在charset字典来确定值,但并不是每一个网站设计都会包含此字段,默认为”ISO…”编码格式,其不一定准确。
apparent_encoding属性,是根据文本内容分析得到的,通常具有较高的准确性。
Request异常与通用代码框架
异常 | 说明 |
---|---|
requests.ConnectionError | 连接错误异常,如DNS查询失败、拒绝连接 |
requests.HTTPError | HTTP错误异常 |
request.URLRequired | URL缺失异常 |
request.ConnectTimeout | 连接远程服务器超时异常 |
request.Timeout | 请求URL超时异常 |
请求异常可以分为以上几种,但并不需要记录,知道即可。
检测异常方法 | 说明 |
---|---|
r.raise_for_status() | 若果不是200,产生异常request.HTTPError |
上述方法用于检测是否出现异常,常用。
一下通用代码框架可用于常见爬虫框架。
1 | import requests |
Robots协议
此协议是针对爬虫所指定的规范,哪些可以爬,哪些不能爬。通常直接放置在根目录下。例如百度”https://www.baidu.com/robots.txt".并截取如下展示:
1 | User-agent: Baiduspider |
- user-agent:爬取框架/爬取人
- Disallow:不允许爬取的内容通配符
BeautifulSoup库
BeautifulSoup可用于爬虫过程第二步,对HTML进行树结构解析,并提供了相对完备的遍历方法。
BeautifulSoup的基本使用
使用很简单,指定HTML地址与解析方式即可。
1 | # 将纯文本文件转换为树形结构,并进行解析便是BeautifulSoup的作用 |
soup对象的基本元素
基本元素 | 说明 |
---|---|
Tag | 标签,基本的信息组织单元,分别用<>和</>表明开头与结尾 |
Name | 标签名,p标签,a标签等,使用格式:Tag.name |
Attributes | 标签属性,字典形式组织,使用格式: Tag.attrs |
NavigableString | 标签内非属性字符串,使用格式:Tag.string |
Comment | 标签内字符串的注释部分, |
由上表可知,soup内对象基本元素的调用,以Tag元素为基础进行。
Tag标签的调用
直接通过标签名称调用即可
1 | soup = bs("htmladress","html.parser") |
- name,标签名的获得
1 | soup = bs("htmladress","html.parser") |
- attrs,标签属性的获得
1 | soup = bs("htmladress","html.parser") |
- NavigableString,标签内非属性字符串的获得
1 | soup = bs("htmladress","html.parser") |
Comment,标签内部Comment获得,比较特殊
并没有一个为comment的属性直接进行提取Comment,但是可通过上述的.string方式获得Comment内容,不同处在于其列别可通过type()函数进行鉴别。
1 | newsoup = BeautifulSoup("<b><!-- this is comment --><p>This is not comment</p></b>") |
下图为熟知的HTML格式,其与BeautifulSoup基本是一一对应的。
BS的遍历
BeautifulSoup对于树的遍历方式,并没有特殊的内容,这里仅做简单的介绍,知道即可。重点还是在应用中的情形。
三种遍历方式:上行、下行、平行
- 下行遍历方法展示
属性 | 说明 |
---|---|
.content | 子节点的列表,将所有子节点信息存入列表 |
.children | 子节点的迭代类型,用于循环遍历子节点情形 |
.descendants | 子孙节点的迭代类型,包含所有的子孙节点,用于遍历 |
- 上行遍历方法展示
属性 | 说明 |
---|---|
.parent | 节点的父节点标签 |
.parents | 节点的祖先节点标签,用于循环遍历 |
- 平行遍历方法展示
属性 | 说明 |
---|---|
.next_sibling | 返回HTML文本顺序中下一个平行节点标签 |
.previous_sibling | 返回HTML文本顺序中上一个平行节点标签 |
.next_siblings | 迭代类型,返回HTML文本顺序中后序所有平行节点标签 |
.previous_siblings | 迭代类型,返回HTML文本顺序中前序所有平行节点标签 |
注意:平行遍历指的是在同一个父节点的前提下,而不是树中所有同一层次的情况。如图:
Bs4的遍历情况总结如图:
信息标注方式与信息提取方法
信息标注方式简介
常见的信息标注方式有三种,分别是XML、JSON、YAML。HTML是XML的变种,也属于XML格式。下面简单的介绍比较三种信息标注方式。
- XML:eXtensible Markup Language , 其构成单位是Tag标签,且标签内包含有名称属性等信息如图:
其中空元素可通过一个<>表示 , 注释通过<!-- --> 表示
1 | #XML空元素表示 |
总结:XML格式共包含三种样式
1 | <name> ... </name> |
- JSON:JavaScript Object Notation , 有类型的键值对表示方式
总结:JSON格式包含三种样式
1 | #普通键值对表示 |
- YAML:Ain’t Markup Language , 无类型键值对
其表示各种关系情况:
1 | #缩进表示所属关系,同Python |
总结:三种表示形式如下
1 | key : value |
信息标注方式实例比较
XML:
1 | <person> |
JSON:
1 | { |
YAML:
1 | firstName: Tian |
信息提取的三种方法
这里的信息提取指的是提取标注信息(xml、json、yaml)内容。
完整解析信息标记,再提取关键信息,需要标记解析器,如BS4。虽然准确但是繁琐,速度慢。
无视标记形式,直接搜索关键信息。对信息文本直接查找。提取速度快,但准确性不确定。
融合方法,一般先通过第二种方式确定范围,再使用第一种方式精确处理。如图
基于Bs4库的HTML内容查找方法
由于本部分内容过于简单,更多的需要在实践中应用,故未详细说明。正则表达式也可以用于检索。
- 首先利用find_all()方法,无视标记形式,直接搜索关键信息。
- 其次解析其标签格式
实例代码
1 | #定向页面爬取 |