Python网络爬虫
该主题主要是掌握定向网络数据爬取和网页解析的基本能力。
核心观点是:The Website is the API...
# Request库
Request (opens new window)库是一个优秀的Python第三方网络请求库。
![image-20210221164233987](python-crawler.assets/image-20210221164233987.png)
# Request的7个主要方法
![image-20210221164321265](python-crawler.assets/image-20210221164321265.png)
# requests.request()
![image-20210221195401463](python-crawler.assets/image-20210221195401463.png)
method为请求方式,有7种方式
url为访问的url链接
**kwargs: 控制访问的参数,均为可选项
params : 字典或字节序列,作为参数增加到url中
data : 字典、字节序列或文件对象,作为Request的内容
json : JSON格式的数据,作为Request的内容
headers : 字典,HTTP定制头
cookies : 字典或CookieJar,Request中的cookie
auth : 元组,支持HTTP认证功能
files : 字典类型,传输文件
timeout : 设定超时时间,秒为单位
proxies : 字典类型,设定访问代理服务器,可以增加登录认证
allow_redirects : True/False,默认为True,重定向开关
stream : True/False,默认为True,获取内容立即下载开关
verify : True/False,默认为True,认证SSL证书开关
cert : 本地SSL证书路径
# requests.get()
![image-20210221173218649](python-crawler.assets/image-20210221173218649.png)
![image-20210221173233864](python-crawler.assets/image-20210221173233864.png)
深入解析,看get()方法的源码,可以发现,其本质是调用request()方法。
![image-20210221173507130](python-crawler.assets/image-20210221173507130.png)
# requests.head()
![image-20210221201429579](python-crawler.assets/image-20210221201429579.png)
# requests.post()
![image-20210221201444158](python-crawler.assets/image-20210221201444158.png)
# requests.put()
![image-20210221201454199](python-crawler.assets/image-20210221201454199.png)
# requests.patch()
![image-20210221201502887](python-crawler.assets/image-20210221201502887.png)
# requests.delete()
![image-20210221201512095](python-crawler.assets/image-20210221201512095.png)
# Response对象
Response对象包含服务器返回的所有信息,也包含请求的Request信息。
其主要的属性有以下几个方面:
![image-20210221173657886](python-crawler.assets/image-20210221173657886.png)
status_code
只有当其值为200的时候,表示连接成功,其响应内容才能正确获取。
案例
encoding和apprent_encoding
# HTTP协议
HTTP(Hypertext Transfer Protocol)超文本传输协议。
其是一个基于”请求与响应“模式的,无状态的应用层协议
- 请求与响应:是指用户向资源服务器发起请求,资源服务器再根据请求的内容进行响应。
- 无状态:上一个HTTP请求与下一个HTTP请求之间不存在关联关系,是无状态的
- 应用层协议:HTTP协议是属于TCP/IP的应用层协议。
HTTP协议采用URL(统一资源定位符)作为定位网络资源的标识,URL格式如下:
![image-20210221193402502](python-crawler.assets/image-20210221193402502.png)
例如:
- 百度URL:
https://www.baidu.com
- 个人网站URL:
https://www.snake8859.top
对于URL理解:URL是通过HTTP协议存取资源的Internet路径,即一个URL对应一个数据资源。
HTTP协议对于资源的操作,包括以下常见的6种请求方式:
![image-20210221193618631](python-crawler.assets/image-20210221193618631.png)
- 其中GET和HEAD一般用于获取资源的,GET用于获取具体资源,HEAD用于获取资源的头部信息(元信息)
- 剩下4种,主要是用于操作资源
![image-20210221193944304](python-crawler.assets/image-20210221193944304.png)
理解PATCH和PUT的区别
假设URL位置有一组数据UserInfo,包括UserID、UserName等20个字段
需求:用户修改了UserName,其他不变
- 采用PATCH,仅向URL提交UserName的局部更新请求
- 采用PUT,必须将所有20个字段一并提交到URL,未提交字段被删除
PATCH的最主要好处:节省网络带宽
# 常见异常及通用代码框架
# 异常处理
网络连接有风险,异常处理很重要。
常见的异常主要有以下几个
![image-20210221174304118](python-crawler.assets/image-20210221174304118.png)
我们可以通过r.raise_for_status()
方法,来对异常进行判断处理。
![image-20210221174404887](python-crawler.assets/image-20210221174404887.png)
# 通用爬虫代码框架(简单版)
![image-20210221192917850](python-crawler.assets/image-20210221192917850.png)
# 网络爬虫引发的问题
![image-20210221201607399](python-crawler.assets/image-20210221201607399.png)
# “性能骚扰”
![image-20210221201618142](python-crawler.assets/image-20210221201618142.png)
# 法律风险
![image-20210221201627269](python-crawler.assets/image-20210221201627269.png)
# 隐私泄露
![image-20210221201715903](python-crawler.assets/image-20210221201715903.png)
# 网络爬虫限制
# 来源审查:判断User-Agent
检查来访HTTP协议头的User‐Agent域,只响应浏览器或友好爬虫的访问
# 发布公告:Robots协议
告知所有爬虫网站的爬取策略,要求爬虫遵守
# Robots协议
Robots Exclusion Standard,网络爬虫排除标准。
作用: 网站告知网络爬虫哪些页面可以抓取,哪些不行
形式: 在网站根目录下的robots.txt文件
案例:
![image-20210221201804032](python-crawler.assets/image-20210221201804032.png)
# 实例(简单版)
# 实例1:京东商品页面的爬取(演示基本使用)
![image-20210221202307393](python-crawler.assets/image-20210221202307393.png)
![image-20210221202234681](python-crawler.assets/image-20210221202234681.png)
一般text内容太多的时候,可以使用切片方式,取1000行,以避免输出太多内容,导致卡顿。
# 实例2:亚马逊商品页面的爬取(演示User-Agent)
![image-20210221202545753](python-crawler.assets/image-20210221202545753.png)
![image-20210221202254496](python-crawler.assets/image-20210221202254496.png)
若不设置请求头的来源请求,模拟一个浏览器,则无法进行获取。
![]()
因为有些网站,对脚本请求一律拒绝。只有浏览器来源的才接受。
# 实例3:百度/360搜索关键字提交(演示POST)
百度的关键词接口: http://www.baidu.com/s?wd=keyword
360的关键词接口: http://www.so.com/s?q=keyword
![image-20210221203011316](python-crawler.assets/image-20210221203011316.png)
# 实例4:网络图片的爬取和存储(演示数据存储)
![image-20210221203032894](python-crawler.assets/image-20210221203032894.png)
# 实例5:IP地址归属地的自动查询(演示调用API)
![image-20210221203059098](python-crawler.assets/image-20210221203059098.png)
通过network里查询某些功能性网站的URL请求,通过URL发起网络请求,达到实时功能。
![image-20210221203049174](python-crawler.assets/image-20210221203049174.png)
学会以爬虫视角看待网络内容。
# Beautiful Soup库
Beautiful Soup (opens new window),又称美丽汤,是一个优秀的第三方Python解析格式库。它能够有效的解析HTML和XML等格式数据。
![image-20210222200827638](python-crawler.assets/image-20210222200827638.png)
Beautiful Soup库是解析、遍历、维护“标签树”的功能库。
![image-20210222201011481](python-crawler.assets/image-20210222201011481.png)
BeautifulSoup对应一个HTML/XML文档的全部内容
Beautiful Soup库,也叫beautifulsoup4 或 bs4。约定引用方式如下,即主要是用BeautifulSoup 类。
![image-20210222200859748](python-crawler.assets/image-20210222200859748.png)
# bs4库的解析器
bs4库提供了以下四种解析器:
![image-20210222201741382](python-crawler.assets/image-20210222201741382.png)
除了
html.parser
解析器,其他的都需要再额外安装相应的库来支持。
案例:
![image-20210222201821899](python-crawler.assets/image-20210222201821899.png)
# bs4库的基本元素
在HTML的标签元素,可对应bs4库内的基本元素。
![image-20210222201912282](python-crawler.assets/image-20210222201912282.png)
接下来以<p></p>
标签为例:
![image-20210222202059613](python-crawler.assets/image-20210222202059613.png)
# Tag标签
![image-20210222201941541](python-crawler.assets/image-20210222201941541.png)
# Tag的name
![image-20210222201958374](python-crawler.assets/image-20210222201958374.png)
# Tag的attrs
![image-20210222202011166](python-crawler.assets/image-20210222202011166.png)
# Tag的NavigableString
![image-20210222202024133](python-crawler.assets/image-20210222202024133.png)
# Tag的Comment
![image-20210222202040304](python-crawler.assets/image-20210222202040304.png)
# 基于bs4库的HTML内容遍历方法
HTML是由标签形成的树形结构,对于HTML的遍历主要有三种方式,分别是下行遍历,上行遍历和平行遍历。
![image-20210222202230460](python-crawler.assets/image-20210222202230460.png)
接下来以该HTML结构为例,进行展开。
![image-20210222202320390](python-crawler.assets/image-20210222202320390.png)
# 下行遍历
![image-20210222202424038](python-crawler.assets/image-20210222202424038.png)
![image-20210222202400796](python-crawler.assets/image-20210222202400796.png)
案例:
![image-20210222202341813](python-crawler.assets/image-20210222202341813.png)
# 上行遍历
![image-20210222202451045](python-crawler.assets/image-20210222202451045.png)
案例:
![image-20210222202513661](python-crawler.assets/image-20210222202513661.png)
![image-20210222202523860](python-crawler.assets/image-20210222202523860.png)
# 平行遍历
![image-20210222202535004](python-crawler.assets/image-20210222202535004.png)
![image-20210222202713961](python-crawler.assets/image-20210222202713961.png)
![image-20210222202632165](python-crawler.assets/image-20210222202632165.png)
注意:平行遍历发生在同一父节点下的各节点间。
案例:
![image-20210222202646694](python-crawler.assets/image-20210222202646694.png)
# 基于bs4库的HTML格式输出
# prettify()方法
prettify() 为HTML文本<>及其内容增加更加'\n'。
![image-20210222202821033](python-crawler.assets/image-20210222202821033.png)
prettify()可用于标签。
![image-20210222202829955](python-crawler.assets/image-20210222202829955.png)
# bs4库的编码
bs4库将任何HTML输入都变成utf‐8编码。
Python 3.x默认支持编码是utf‐8,解析无障碍。
![image-20210222202920786](python-crawler.assets/image-20210222202920786.png)
# 信息标记
所谓信息标记,即为描述信息的信息说明。
![image-20210222202949636](python-crawler.assets/image-20210222202949636.png)
例如上述信息中的name
和addr
是对于信息描述的信息,用于解释信息的含义。
- 标记后的信息可形成信息组织结构,增加了信息维度
- 标记的结构与信息一样具有重要价值
- 标记后的信息可用于通信、存储或展示
- 标记后的信息更利于程序理解和运用
目前国际主流的对信息标记的格式主要有三种,分别是XML,JSON和YAML。
# XML
XML(eXtensible Markup Language),是用一组自定义标签来对信息进行标记的方式。
![image-20210222203213068](python-crawler.assets/image-20210222203213068.png)
标签一般包括,标签名,属性和内容等。
![image-20210222203244604](python-crawler.assets/image-20210222203244604.png)
# JSON
JSON(JavsScript Object Notation),是用有类型的键值对key:value
来对信息进行标记的方式。
![image-20210222203322930](python-crawler.assets/image-20210222203322930.png)
多值表达:
![image-20210222203333556](python-crawler.assets/image-20210222203333556.png)
嵌套表达:
![image-20210222203402723](python-crawler.assets/image-20210222203402723.png)
# YAML
YAML( Ain’t Markup Language),是用无类型键值对key:value
来对信息进行标记的方式。
![image-20210222203442603](python-crawler.assets/image-20210222203442603.png)
其利用缩进方式表达所属关系(类似于Python的缩进)
![image-20210222203518907](python-crawler.assets/image-20210222203518907.png)
其利用-
来表达并列关系。
![image-20210222203544660](python-crawler.assets/image-20210222203544660.png)
其还可以用|
来表达整块数据,用#
表示注释。
![image-20210222203613243](python-crawler.assets/image-20210222203613243.png)
总结:
![image-20210222203635449](python-crawler.assets/image-20210222203635449.png)
# 同一数据用三者表达效果
XML表达
JSON表达
YAML表达
# 三者比较
XML:最早的通用信息标记语言,可扩展性好,但繁琐。
适用范围:Internet上的信息交互与传递
JSON:信息有类型,适合程序处理(js),较XML简洁
适用范围:移动应用云端和节点的信息通信,无注释
YAML:信息无类型,文本信息比例最高,可读性好
适用范围:各类系统的配置文件,有注释易读
# 信息提取
# 方法一
**完整解析信息的标记形式,再提取关键信息。**一般需要配合标记解析器,例如:bs4库的标签树遍历。
- 优点:信息解析准确
- 缺点:提取过程繁琐,速度慢
# 方法二
**无视标记形式,直接搜索关键信息。**对信息的文本查找函数即可。
- 优点:提取过程简洁,速度较快
- 缺点:提取结果准确性与信息内容相关
# 融合方法
结合形式解析与搜索方法,提取关键信息。
需要标记解析器及文本查找函数。
案例:
![image-20210222204047639](python-crawler.assets/image-20210222204047639.png)
# 基于bs4库的HTML内容查找方法
# find_all()方法
soup的find_all()方法,用于搜索到所查找的标签。
name
当name为Ture时,相当于
*
匹配所有。name也可以配合正则表达式,进行特定匹配,例如匹配以b开头的标签。
attrs
attr可以配合正则表达式
recursive
string
# 扩展方法
![image-20210222204632713](python-crawler.assets/image-20210222204632713.png)
# 实例
# 中国大学排名定向爬虫
![image-20210222204917512](python-crawler.assets/image-20210222204917512.png)
功能描述
- 输入:大学排名URL链接
- 输出:大学排名信息的屏幕输出(排名,大学名称,总分)
- 技术路线:requests‐bs4
- 定向爬虫:仅对输入URL进行爬取,不扩展爬取
程序的结构设计
- 从网络上获取大学排名网页内容
- 提取网页内容中信息到合适的数据结构
- 利用数据结构展示并输出结果
![image-20210222205022541](python-crawler.assets/image-20210222205022541.png)
# Re库
RE(regular expression),正则表达式的理解:
- 正则表达式是用来简洁表达一组字符串的表达式。
- 正则表达式是一种通用的字符串表达框架。
- 正则表达式是一种针对字符串表达“简洁”和“特征”思想的工具 正则表达式可以用来判断某字符串的特征归属
![image-20210224144250158](python-crawler.assets/image-20210224144250158.png)
# 正则表达式的语法
正则表达式语法由字符和操作符构成。
![image-20210224145216579](python-crawler.assets/image-20210224145216579.png)
# 常用操作符
![image-20210224145234934](python-crawler.assets/image-20210224145234934.png)
![image-20210224145249176](python-crawler.assets/image-20210224145249176.png)
实例:
![image-20210224145305418](python-crawler.assets/image-20210224145305418.png)
经典正则表达式:
![image-20210224145321503](python-crawler.assets/image-20210224145321503.png)
更多具体的可参考传送门 (opens new window)
# Re库基本使用
Re库是Python的标准库,主要用于字符串匹配。
调用方式:
![image-20210224145504988](python-crawler.assets/image-20210224145504988.png)
# 正则表达式的表示类型
raw string类型(原生字符串类型)
re库采用raw string类型表示正则表达式,表示为:
面向对象类型(complie编译)
# Re库主要功能函数
![image-20210224145712635](python-crawler.assets/image-20210224145712635.png)
# re.search()
![image-20210224145744725](python-crawler.assets/image-20210224145744725.png)
flags常见标记
案例:
![image-20210224145825849](python-crawler.assets/image-20210224145825849.png)
# re.match()
![image-20210224145853845](python-crawler.assets/image-20210224145853845.png)
案例:
![image-20210224145930247](python-crawler.assets/image-20210224145930247.png)
# re.findall()
![image-20210224145947530](python-crawler.assets/image-20210224145947530.png)
案例:
![image-20210224150020916](python-crawler.assets/image-20210224150020916.png)
# re.split()
![image-20210224150042663](python-crawler.assets/image-20210224150042663.png)
案例:
![image-20210224150102806](python-crawler.assets/image-20210224150102806.png)
# re.finditer()
![image-20210224150123593](python-crawler.assets/image-20210224150123593.png)
案例:
![image-20210224150139117](python-crawler.assets/image-20210224150139117.png)
# re.sub()
![image-20210224150159629](python-crawler.assets/image-20210224150159629.png)
![image-20210224150211692](python-crawler.assets/image-20210224150211692.png)
# Re库的Match对象
Match对象是一次匹配的结果,包含匹配的很多信息。
![image-20210224150516732](python-crawler.assets/image-20210224150516732.png)
# Match对象的属性
![image-20210224150611584](python-crawler.assets/image-20210224150611584.png)
# Match对象的方法
![image-20210224150629101](python-crawler.assets/image-20210224150629101.png)
# 实例
![image-20210224150702508](python-crawler.assets/image-20210224150702508.png)
# Re库的贪婪匹配和最小匹配
![image-20210224150736661](python-crawler.assets/image-20210224150736661.png)
# 贪婪匹配
![image-20210224150758600](python-crawler.assets/image-20210224150758600.png)
# 最小匹配
如何输出最短的子串呢?
![image-20210224150825970](python-crawler.assets/image-20210224150825970.png)