Python网络爬虫

2/24/2021

该主题主要是掌握定向网络数据爬取和网页解析的基本能力。

核心观点是:The Website is the API...

# Request库

Request (opens new window)库是一个优秀的Python第三方网络请求库。

image-20210221164233987

# Request的7个主要方法

image-20210221164321265

# requests.request()

image-20210221195401463
  • method为请求方式,有7种方式

    image-20210221195911880
  • url为访问的url链接

  • **kwargs: 控制访问的参数,均为可选项

    1. params : 字典或字节序列,作为参数增加到url中

      image-20210221200334112
    2. data : 字典、字节序列或文件对象,作为Request的内容

      image-20210221200500215
    3. json : JSON格式的数据,作为Request的内容

      image-20210221200935438
    4. headers : 字典,HTTP定制头

      image-20210221200954533
    5. cookies : 字典或CookieJar,Request中的cookie

    6. auth : 元组,支持HTTP认证功能

    7. files : 字典类型,传输文件

      image-20210221201102125
    8. timeout : 设定超时时间,秒为单位

      image-20210221201201047
    9. proxies : 字典类型,设定访问代理服务器,可以增加登录认证

      image-20210221201253107
    10. allow_redirects : True/False,默认为True,重定向开关

    11. stream : True/False,默认为True,获取内容立即下载开关

    12. verify : True/False,默认为True,认证SSL证书开关

    13. cert : 本地SSL证书路径

# requests.get()

image-20210221173218649 image-20210221173233864

深入解析,看get()方法的源码,可以发现,其本质是调用request()方法。

image-20210221173507130

# requests.head()

image-20210221201429579

# requests.post()

image-20210221201444158

# requests.put()

image-20210221201454199

# requests.patch()

image-20210221201502887

# requests.delete()

image-20210221201512095

# Response对象

Response对象包含服务器返回的所有信息,也包含请求的Request信息。

其主要的属性有以下几个方面:

image-20210221173657886
  • status_code

    image-20210221173803558

    只有当其值为200的时候,表示连接成功,其响应内容才能正确获取。

    案例

    image-20210221173859721
  • encoding和apprent_encoding

    image-20210221174215479

# HTTP协议

HTTP(Hypertext Transfer Protocol)超文本传输协议。

其是一个基于”请求与响应“模式的,无状态的应用层协议

  • 请求与响应:是指用户向资源服务器发起请求,资源服务器再根据请求的内容进行响应。
  • 无状态:上一个HTTP请求与下一个HTTP请求之间不存在关联关系,是无状态的
  • 应用层协议:HTTP协议是属于TCP/IP的应用层协议。

HTTP协议采用URL(统一资源定位符)作为定位网络资源的标识,URL格式如下:

image-20210221193402502

例如:

  • 百度URL:https://www.baidu.com
  • 个人网站URL:https://www.snake8859.top

对于URL理解:URL是通过HTTP协议存取资源的Internet路径,即一个URL对应一个数据资源。

HTTP协议对于资源的操作,包括以下常见的6种请求方式:

image-20210221193618631
  • 其中GET和HEAD一般用于获取资源的,GET用于获取具体资源,HEAD用于获取资源的头部信息(元信息)
  • 剩下4种,主要是用于操作资源
image-20210221193944304

理解PATCH和PUT的区别

假设URL位置有一组数据UserInfo,包括UserID、UserName等20个字段

需求:用户修改了UserName,其他不变

  • 采用PATCH,仅向URL提交UserName的局部更新请求
  • 采用PUT,必须将所有20个字段一并提交到URL,未提交字段被删除

PATCH的最主要好处:节省网络带宽

# 常见异常及通用代码框架

# 异常处理

网络连接有风险,异常处理很重要

常见的异常主要有以下几个

image-20210221174304118

我们可以通过r.raise_for_status()方法,来对异常进行判断处理。

image-20210221174404887

# 通用爬虫代码框架(简单版)

image-20210221192917850

# 网络爬虫引发的问题

image-20210221201607399

# “性能骚扰”

image-20210221201618142

# 法律风险

image-20210221201627269

# 隐私泄露

image-20210221201715903

# 网络爬虫限制

# 来源审查:判断User-Agent

检查来访HTTP协议头的User‐Agent域,只响应浏览器或友好爬虫的访问

# 发布公告:Robots协议

告知所有爬虫网站的爬取策略,要求爬虫遵守

# Robots协议

Robots Exclusion Standard,网络爬虫排除标准。

作用: 网站告知网络爬虫哪些页面可以抓取,哪些不行

形式: 在网站根目录下的robots.txt文件

案例:

image-20210221201804032

# 实例(简单版)

# 实例1:京东商品页面的爬取(演示基本使用)

image-20210221202307393 image-20210221202234681

一般text内容太多的时候,可以使用切片方式,取1000行,以避免输出太多内容,导致卡顿。

# 实例2:亚马逊商品页面的爬取(演示User-Agent)

image-20210221202545753 image-20210221202254496

若不设置请求头的来源请求,模拟一个浏览器,则无法进行获取。

image-20210221202724873

因为有些网站,对脚本请求一律拒绝。只有浏览器来源的才接受。

image-20210221202812679

# 实例3:百度/360搜索关键字提交(演示POST)

百度的关键词接口: http://www.baidu.com/s?wd=keyword

360的关键词接口: http://www.so.com/s?q=keyword

image-20210221203011316

# 实例4:网络图片的爬取和存储(演示数据存储)

image-20210221203032894

# 实例5:IP地址归属地的自动查询(演示调用API)

image-20210221203059098

通过network里查询某些功能性网站的URL请求,通过URL发起网络请求,达到实时功能。

image-20210221203049174

学会以爬虫视角看待网络内容。

# Beautiful Soup库

Beautiful Soup (opens new window),又称美丽汤,是一个优秀的第三方Python解析格式库。它能够有效的解析HTML和XML等格式数据。

image-20210222200827638

Beautiful Soup库是解析、遍历、维护“标签树”的功能库。

image-20210222201011481

BeautifulSoup对应一个HTML/XML文档的全部内容

Beautiful Soup库,也叫beautifulsoup4 或 bs4。约定引用方式如下,即主要是用BeautifulSoup 类。

image-20210222200859748

# bs4库的解析器

bs4库提供了以下四种解析器:

image-20210222201741382

除了html.parser解析器,其他的都需要再额外安装相应的库来支持。

案例:

image-20210222201821899

# bs4库的基本元素

在HTML的标签元素,可对应bs4库内的基本元素。

image-20210222201912282

接下来以<p></p>标签为例:

image-20210222202059613

# Tag标签

image-20210222201941541

# Tag的name

image-20210222201958374

# Tag的attrs

image-20210222202011166

# Tag的NavigableString

image-20210222202024133

# Tag的Comment

image-20210222202040304

# 基于bs4库的HTML内容遍历方法

HTML是由标签形成的树形结构,对于HTML的遍历主要有三种方式,分别是下行遍历,上行遍历和平行遍历。

image-20210222202230460

接下来以该HTML结构为例,进行展开。

image-20210222202320390

# 下行遍历

image-20210222202424038 image-20210222202400796

案例:

image-20210222202341813

# 上行遍历

image-20210222202451045

案例:

image-20210222202513661 image-20210222202523860

# 平行遍历

image-20210222202535004 image-20210222202713961 image-20210222202632165

注意:平行遍历发生在同一父节点下的各节点间。

image-20210222202611543

案例:

image-20210222202646694

# 基于bs4库的HTML格式输出

# prettify()方法

prettify() 为HTML文本<>及其内容增加更加'\n'。

image-20210222202821033

prettify()可用于标签。

image-20210222202829955

# bs4库的编码

bs4库将任何HTML输入都变成utf‐8编码。

Python 3.x默认支持编码是utf‐8,解析无障碍。

image-20210222202920786

# 信息标记

所谓信息标记,即为描述信息的信息说明。

image-20210222202949636

例如上述信息中的nameaddr是对于信息描述的信息,用于解释信息的含义。

  • 标记后的信息可形成信息组织结构,增加了信息维度
  • 标记的结构与信息一样具有重要价值
  • 标记后的信息可用于通信、存储或展示
  • 标记后的信息更利于程序理解和运用

目前国际主流的对信息标记的格式主要有三种,分别是XML,JSON和YAML。

# XML

XML(eXtensible Markup Language),是用一组自定义标签来对信息进行标记的方式。

image-20210222203213068

标签一般包括,标签名,属性和内容等。

image-20210222203244604

# JSON

JSON(JavsScript Object Notation),是用有类型的键值对key:value来对信息进行标记的方式。

image-20210222203322930

多值表达:

image-20210222203333556

嵌套表达:

image-20210222203402723

# YAML

YAML( Ain’t Markup Language),是用无类型键值对key:value来对信息进行标记的方式。

image-20210222203442603

其利用缩进方式表达所属关系(类似于Python的缩进)

image-20210222203518907

其利用-来表达并列关系。

image-20210222203544660

其还可以用|来表达整块数据,用#表示注释。

image-20210222203613243

总结:

image-20210222203635449

# 同一数据用三者表达效果

  • XML表达

    image-20210222203814432
  • JSON表达

    image-20210222203833814
  • YAML表达

    image-20210222203847612

# 三者比较

  • XML:最早的通用信息标记语言,可扩展性好,但繁琐。

    适用范围:Internet上的信息交互与传递

  • JSON:信息有类型,适合程序处理(js),较XML简洁

    适用范围:移动应用云端和节点的信息通信,无注释

  • YAML:信息无类型,文本信息比例最高,可读性好

    适用范围:各类系统的配置文件,有注释易读

# 信息提取

# 方法一

**完整解析信息的标记形式,再提取关键信息。**一般需要配合标记解析器,例如:bs4库的标签树遍历。

  • 优点:信息解析准确
  • 缺点:提取过程繁琐,速度慢

# 方法二

**无视标记形式,直接搜索关键信息。**对信息的文本查找函数即可。

  • 优点:提取过程简洁,速度较快
  • 缺点:提取结果准确性与信息内容相关

# 融合方法

结合形式解析与搜索方法,提取关键信息。

需要标记解析器及文本查找函数。

案例:

image-20210222204047639

# 基于bs4库的HTML内容查找方法

# find_all()方法

soup的find_all()方法,用于搜索到所查找的标签。

  • name

    image-20210222204108343

    当name为Ture时,相当于*匹配所有。

    image-20210222204310396

    name也可以配合正则表达式,进行特定匹配,例如匹配以b开头的标签。

    image-20210222204355234
  • attrs

    image-20210222204416309

    attr可以配合正则表达式

    image-20210222204514531
  • recursive

    image-20210222204536944
  • string

    image-20210222204556948 image-20210222204611478

# 扩展方法

image-20210222204632713

# 实例

# 中国大学排名定向爬虫

目标网站:最好大学网 (opens new window)

image-20210222204917512

功能描述

  • 输入:大学排名URL链接
  • 输出:大学排名信息的屏幕输出(排名,大学名称,总分)
  • 技术路线:requests‐bs4
  • 定向爬虫:仅对输入URL进行爬取,不扩展爬取

程序的结构设计

  1. 从网络上获取大学排名网页内容
  2. 提取网页内容中信息到合适的数据结构
  3. 利用数据结构展示并输出结果

image-20210222205013274

image-20210222205022541

# Re库

RE(regular expression),正则表达式的理解:

  • 正则表达式是用来简洁表达一组字符串的表达式。
  • 正则表达式是一种通用的字符串表达框架。
  • 正则表达式是一种针对字符串表达“简洁”和“特征”思想的工具 正则表达式可以用来判断某字符串的特征归属
image-20210224144250158

# 正则表达式的语法

正则表达式语法由字符操作符构成。

image-20210224145216579

# 常用操作符

image-20210224145234934 image-20210224145249176

实例:

image-20210224145305418

经典正则表达式:

image-20210224145321503

更多具体的可参考传送门 (opens new window)

# Re库基本使用

Re库是Python的标准库,主要用于字符串匹配。

调用方式:

image-20210224145504988

# 正则表达式的表示类型

  • raw string类型(原生字符串类型)

    re库采用raw string类型表示正则表达式,表示为:

    image-20210224145633776
  • 面向对象类型(complie编译)

    image-20210224150329104 image-20210224150343818

# Re库主要功能函数

image-20210224145712635 image-20210224145744725
  • flags常见标记

    image-20210224145804653

案例:

image-20210224145825849

# re.match()

image-20210224145853845

案例:

image-20210224145930247

# re.findall()

image-20210224145947530

案例:

image-20210224150020916

# re.split()

image-20210224150042663

案例:

image-20210224150102806

# re.finditer()

image-20210224150123593

案例:

image-20210224150139117

# re.sub()

image-20210224150159629 image-20210224150211692

# Re库的Match对象

Match对象是一次匹配的结果,包含匹配的很多信息。

image-20210224150516732

# Match对象的属性

image-20210224150611584

# Match对象的方法

image-20210224150629101

# 实例

image-20210224150702508

# Re库的贪婪匹配和最小匹配

image-20210224150736661

# 贪婪匹配

image-20210224150758600

# 最小匹配

如何输出最短的子串呢?

image-20210224150825970

# Scrapy爬虫框架

Last Updated: 11/21/2022, 10:03:43 PM