网络请求与数据提取-urllib库

news2024/9/26 5:12:34

关于网络爬虫,其实就是模拟浏览器向网站服务器发送请求,然后从响应的结果中提取出需要的数据。那么,该如何实现这一流程了?对于初学者来说,可能都不知道该如何入手,学习爬虫时需不需要了解HTTP、TCP、IP 层的网络传输通信和知道服务器的响应和应答原理,以及请求的这个数据结构需要自己实现吗,等等一系列问题产生疑惑。

    不用担心,Python的强大之处就是提供了功能齐全的类库来帮助我们完成这些请求。最基础的 HTTP 库有 urllib、httplib2、requests、treq 等。就以 requests 库来说,有了它,我们只需要关注请求的链接是什么,需要传什么参数,以及如何设置请求头就可以了,不用深入地去看它的底层是怎样传输和通信的。

接下来,本篇内容中,笔者将先讲解如何使用Python里面的网络请求库对指定的网站地址发起一个请求并获取响应结果。然后讲解从结果中根据规则提取出指定的信息。

本篇主要涉及的知识点

    □ 网络请求库的使用

    □ 使用xpath表达式提取网页数据

    □ 使用正则表达式提取数据

1.Python内置网络请求库 urllib

urllib 是 Python 中内置的一个用于网络请求的库,通过它可以实现模拟浏览器发送 HTTP 请求和获取请求返回结果等。本文将对 urllib 的基本使用进行讲解和演示。零基础读者在学习过程中可以跟着案例一边学习,一边动手操作。

1.1 请求一个简单的网页

在学习如何使用 urllib 发起网络请求之前,我们先来看一个网页,看看它的页面和源码长什么样,以百度百科的首页地址为例:

https://baike.baidu.com/

使用浏览器打开该网址之后,会出现如图1所示的页面。

图1

 接着,再在页面任意位置上鼠标右击,在弹出的快捷菜单中选择【查看网页源码】命令,即可查看到该网页的 HTML 源代码,如图2所示。

图2

 接下来我们的目标是要使用 urllib 库模拟浏览器发起一个 HTTP 请求去获取此网页源码,得到的内容要跟我们直接在浏览器上看到的源码一样。要实现这个功能,就需要用到 urllib.request 模块。 通过 urllib.request 模块的 urlopen() 方法就可以对网页发起请求和获取返回结果。语法格式如下:

urllib.request.urlopen(
     url,
     data=None,
     [timeout, ]*,
     cafile=None,
     capath=None,
     context=None
)

从语法格式中可以看到,在使用 urlopen() 方法的时候,需要传递很多的参数,事实上大多数时候只需要关注前面的 url、data、timeout 这 3 个参数就行。这些参数的具体含义如下。

    (1)url 参数:String 类型的地址,也就是我们要访问的 URL。

    (2)data:参数指的是在请求的时候,需要提交的数据。

    (3)timeout:参数用于设置请求超时时间,单位是秒。

    (4)cafile 和 capath:代表 CA 证书和 CA 证书的路径,如果使用 HTTPS,则需要用到。

    (5)context 参数:用来指定 SSL 设置,必须是 ssl.SSLContext 类型。

这里只是为了获取该网页的源码,所以只需要传入 url 参数进行请求即可。请求完之后,会返回一个结果,再通过这个结果的 read() 方法便可以获取到真正的网页源码,示例代码如下:

import urllib.request

url = "https://baike.baidu.com/"
response = urllib.request.urlopen(url)
html = response.read()
print(html.decode('utf-8'))

通过示例代码可看到,在使用 urllib.request 模块之前,需要先使用 import 关键词进行导入。同 理,在本书后面其他的示例代码中也是一样的,特别是新手读者需要多注意,在使用任何模块或库的时候,都需要先导入。在请求获取返回结果之后,如果在控制台输出打印发现有乱码,需要对结果进行解码,如上面代码中所示的decode()方法可以对字符串进行解码。运行代码结果如图3所示。

图3 运行结果

 观察结果中的内容可以发现,我们通过 urllib.request.urlopen() 方法发起请求拿到的结果跟在浏览器中看到的一模一样。至此,我们已经完成使用 urllib.request 模块实现请求第一个网页。

1.2 设置请求超时

在访问网页时常常会碰到这样的情况,因为某些原因,比如自己电脑网络慢或对方网站服务器压力大等,导致在打开网页或刷新的时候迟迟无法得到响应。同样,在程序中去请求的时候也会遇到这样的问题。因此我们可以手动设置超时时间。当爬虫程序在请求某一网站时,迟迟无法获得响应内容,可以采取进一步措施,例如,选择直接丢弃该请求或再请求一次。为了应对这个问题,在 urllib.urlopen() 中可以通过 timeout 这个参数去设置超时时间。下面还是以请求前面给的网页为例, 设置如果请求超过 3 秒未响应内容,就舍弃它或重新尝试访问。示例代码如下:

import urllib.request

url = "https://baike.baidu.com/"
response = urllib.request.urlopen(url,timeout=3)
html = response.read()
print(html.decode('utf-8'))

1.3 使用data参数提交数据

urlopen() 方法里面的参数除了 url、timeout 之外,还有 data 参数也比较常用,data 参数是可选的。 如果要添加 data,它必须是字节流编码格式的内容,即 bytes 类型,通过 bytes() 函数可以进行转化。 另外,如果传递了这个 data 参数,它的请求方式就不再是 GET 方式请求,而是 POST 。所以一般在访问的网站需要使用 post 请求获取数据的情况下,才会传递 data 参数。这里查阅了一个网址可 以进行测试:http://httpbin.org。通过使用 POST 方式访问它的 http://httpbin.org/post 路径并且传递一个参数 word 和值,即可获取类似以下的响应内容. 如图4所示。

图4 响应内容

 接下来我们使用代码实现这个过程,需要使用 urllib.parse.urlencode() 方法将要提交的 data 字典数 据转化为字符串,再使用 bytes()方法转换为字节流,最后使用 urlopen()方法发起请求,示例代码如下:

import urllib.parse
import urllib.request

data = bytes(urllib.parse.urlencode({'word': '22222'}),encoding='utf8')
response = urllib.request.urlopen('http://httpbin.org/post',data=data)
print(response.read())

运行输出结果:

b'{\n  "args": {}, \n  "data": "", \n  "files": {}, \n  "form": {\n    "word": "22222"\n  }, \n  "headers": {\n    "Accept-Encoding": "identity", \n    "Content-Length": "10", \n    "Content-Type": "application/x-www-form-urlencoded", \n    "Host": "httpbin.org", \n    "User-Agent": "Python-urllib/3.10", \n    "X-Amzn-Trace-Id": "Root=1-628a5cd3-2cfb1c893b672ba6115f0fbe"\n  }, \n  "json": null, \n  "origin": "61.141.253.53", \n  "url": "http://httpbin.org/post"\n}\n'

1.4 Request方法

通过前面的知识知道,利用 urlopen() 方法可以发起简单的请求,但 urlopen() 这几个简单的参 数并不足以构建一个完整的请求,如果请求中需要加入 headers(请求头)、指定请求方式等信息, 我们就可以利用 urllib.request 模块中更强大的 Request 类来构建一个请求。其语法格式如下:

urllib.request.Request(
     url,
     data=None,
     headers={},
     origin_req_host=None,
     unverifiable=False,
     method=None
)

同样,通过语法格式可以看到,在使用 Request 方法的时候,也需要传递一些参数,这些参数 的含义如下。

    (1)url 参数:请求链接,这个是必传参数,其他的都是可选参数。

    (2)data 参数:跟 urlopen() 中的 data 参数用法相同。

   (3)headers 参数:指定发起的 HTTP 请求的头部信息。headers 是一个字典。它除了在 Request 中添加,还可以通过调用 Request 实例的 add_header() 方法来添加请求头。

    (4)origin_req_host 参数:指的是请求方的 host 名称或 IP 地址。

    (5)unverifiable 参数:表示这个请求是否合法,默认值是 False。意思就是说用户没有足够权 限来选择接收这个请求的结果。例如,我们请求一个 HTML 文档中的图片,但是没有自动抓取图 像的权限,就要将 unverifiable 的值设置成 True。

    (6)method 参数:指的是发起的 HTTP 请求的方式,有 GET、POST、DELETE、PUT 等。 下面使用它请求一下 https://www.baidu.com 这个网址,网页源码如图 5 所示。

图5 网页源码

 编写代码,首先直接通过 urllib.request.Request() 方法只传入 url 这个参数进行请求,获取百度 首页的源码,示例代码如下:

import urllib.request
url = "https://www.baidu.com"

request = urllib.request.Request(url=url)
response = urllib.request.urlopen(request)
print(response.read().decode('utf-8'))

运行代码之后,发现返回的结果与浏览器上看到的并不一样,如图 6 所示,只返回了少量的 几行代码,而且内容也跟图 5 所示的对不上。这是为什么呢?

这是因为百度这个网站对请求的 headers 信息进行了验证,我们直接使用 Request()方法进行请 求,默认的 User-Agent 是 Python-urllib/ 版本号,百度会识别出来是程序在访问,所以会对其进行 拦截。这时候就需要对 headers 进行伪装,伪装成浏览器上的 header 信息。所以当我们在请求的时候, 就需要传递一个 headers 参数,才能正确地拿到结果。例如下面的示例代码所示,这里将自己的 headers 信息里面的 User-Agent 伪装成了跟浏览器上的一样。

import urllib.request

headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64)AppleWebKit/'
'537.36 (KHTML, like Gecko) Chrome/56.0.2924.87Safari/537.36'
}
url = "https://www.baidu.com"
request = urllib.request.Request(url=url, headers=headers)
response = urllib.request.urlopen(request)
print(response.read().decode('utf-8'))

修改代码,在加上 headers 参数之后,再次运行代码发起请求,将会发现返回的百度首页源代码已经正常了,跟浏览器上看到的一模一样,如图 7 所示。

图7 响应结果

 除此之外,Request方法还可以传递一些其它的参数,不过都不太常用,笔者这里不做讲解,有兴趣的读者可以查阅相关资料进行了解。

下一篇文章:Python第三方网络请求库requests

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/97509.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

入门:环境安装与部署

容器技术入门 随着时代的发展,Docker也逐渐走上了历史舞台,曾经我们想要安装一套环境,需要花费一下午甚至一整天来配置和安装各个部分(比如运行我们自己的SpringBoot应用程序,可能需要安装数据库、安装Redis、安装MQ等…

springboot常用语法库

今天与大家分享springboot常用语法库的基本语法。如果有问题,望大家指教。 目录 1. freemarker是什么 1.1 优点 2. springboot整合freemarker 2.1 pom.xml 2.2 项目配置文件 2.3 Controller 2.4 index.ftl 2.5 常用功能演示 1. freemarker是什么 FreeMarke…

OPENGL ES 2.0 知识串讲 (3)——SHADER的功能GLSL语法(I)

更多图形知识请关注我的公众号: 在第一节中,我们介绍过 OpenGL ES 与 GLSL 的主要功能,就是往绘制 buffer 上绘制图片。其中虽然 GLSL 制作的 shader 是穿插在 OpenGL ES 中使用,但是我们在流程中可以看出来,两大 shader(vertex shader 和 fragment shader)相对于 O…

大学毕业生就业信息管理平台

开发工具(eclipse/idea/vscode等): 数据库(sqlite/mysql/sqlserver等): 功能模块(请用文字描述,至少200字): 系统在功能设计充分利用信息化技术和互联网的优势,建立一个以浏览器为用户工作界面,实现跨 平台…

Hive电子商务消费行为分析项目

文章目录数据说明环境准备项目代码上传数据文件并创建数据表数据清洗数据可视化客户分析交易分析门店分析评价分析数据说明 某零售企业的门店最近一年收集的数据 customer_details.csv:客户信息 transaction_details.csv:交易信息 store_details.csv:门店信息 store_review.c…

第1章 基础知识简介

🌞欢迎来到C语言的世界 🌈博客主页:卿云阁 💌欢迎关注🎉点赞👍收藏⭐️留言📝 🌟本文由卿云阁原创! 🌠本阶段属于练气阶段,希望各位仙友顺利完成…

【机器码】原码、反码、补码的学习

目录 让我们看看这三个码是什么 原码、反码、补码各自的范围 补码的加减运算 根据自己学习做的笔记来记录一下 原码、反码、补码,巩固自己的学习成果。 有符号数是由机器数和真值组合而成 真值:数值数据的实际值,带有-符号 …

RL 实践(3)—— 悬崖漫步【QLearning Sarsa 各种变体】

本文介绍如何用 QLeaning 系列和 Sarsa 系列表格方法解经典的悬崖漫步 (Cliff Walking) 问题完整代码下载:4_[Gym Custom] Cliff Walking (Q-Learning series and Sarsa series) 文章目录1. 悬崖漫步环境 (Cliff Walking)2. 使用 TD 方法求解2.1 Sarsa2.1.1 Sarsa 原…

kali 安装AWVS [赠附件]

前言 1.AWVS简介 AWVS(Acunetix Web Vulnerability Scanner)是一款知名的网络漏洞扫描工具,通过网络爬虫测试网站安全,检测流行的Web应用攻击,如跨站脚本、sql 注入等。据统计,75% 的互联网攻击目标是基于…

项目中遇到的错误

项目中遇到的错误swagger2 和 swagger3swagger 文档的注解springboot 版本问题SQL 关键字异常Apifox 的使用集中版本管理swagger2 和 swagger3 swagger2和 swagger3 需要导入的依赖 <dependency><groupId>io.springfox</groupId><artifactId>springfo…

LabVIEW FPGA中可重入和非可重入子VI的区别

LabVIEW FPGA中可重入和非可重入子VI的区别 LabVIEW FPGAVI默认是可重入的。如果多次调用重入VI&#xff0c;则每个实例会占用FPGA器件的单独硬件资源。如果使用非重入VI&#xff0c;无论是并行多次调用还是仅调用一次&#xff0c;都只会创建一个硬件实例并将其用于该VI。 ​…

最常用的 9 个JavaScript 函数与示例

输出内容才能更好的理解输入的知识 前言&#x1f380; 如果你想深入图形、可视化等领域&#xff0c;那么肯定离不开 canvas、webgl、three.js 等一系列技术。在这众多技术中&#xff0c;选择canvas2d为基础来入门是一个不错的选择。 canvas在动画、可视化、图片处理等领域有着…

物联网通信技术原理 第5章

目录 5.1 移动通信的基本概念及发展历史 5.1.1 移动通信的基本概念 5.1.2 移动通信的发展历史&#xff08;理解&#xff09; 1.第一代移动通信系统(1G) 2.第二代移动通信系统(2G) 3.第三代移动通信系统(3G) 5.1.3 移动通信的发展趋势与展望 5.2 无线传播与移动信道 5.2…

哈希的应用:布隆过滤器(C++实现)

文章目录1. 布隆过滤器1.1 背景1.2 概念1.3 控制误判率2. 实现布隆过滤器2.1 布隆过滤器类2.2 Set2.3 Test2.4 删除3. 优点4. 缺陷4. 缺陷1. 布隆过滤器 1.1 背景 位图&#xff08;bitmap算法&#xff09;告诉我们&#xff0c;想判断一个元素是否存在于某个集合中&#xff0c…

c语言指针 字符 字符串

1、sizeof 某个类型或者某个变量在内存中占用字节数。 例如&#xff1a;sizeof(int) ; sizeof(i)&#xff1b;都可以使用 2、运算符& 获取变量的地址。 int i; scanf("%d",&i); 输入变量时&#xff0c;必须使用&运算符。 &操作符只能应…

机器学习100天(二):002 数据预处理之导入数据集

机器学习 100 天,今天讲的是:数据预处理之导入数据集。 首先,我们打开 spyder。新建一个 load_data.py 脚本。 第一步,导入标准库 机器学习常用的标准库有 3 个: 第一个:numpy,用于数据处理。 第二个:matplotlib.pyplot,用于画图。 第三个:pandas,用于数值分析…

python 爬虫

前言 一、什么是爬虫 爬虫&#xff1a;&#xff08;又称为网页蜘蛛&#xff0c;网络机器人&#xff0c;在 FOAF 社区中间&#xff0c;更经常地称为网页追逐者&#xff09;&#xff1b;它是一种按照一定的规则&#xff0c;自动地从互联网上抓取对于我们有价值的网络信息的程序…

最强大的布局方案——网格Grid布局万字详解

Grid 布局又称网格布局&#xff0c;是W3C提出的一个二维布局系统&#xff0c;它与 Flex 布局有一定的相似性&#xff0c;都可以指定容器内部多个项目的位置。但它们也存在重大区别。Flex 布局是轴线布局&#xff0c;只能指定"项目"针对轴线的位置&#xff0c;可以看作…

jsp+ssm计算机毕业设计大学城二手书交易网站【附源码】

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; JSPSSM mybatis Maven等等组成&#xff0c;B/S模式 Mave…

绝对神器,今天教你如何识别图片上竖排的日语文字

在文字翻译或者其他的工作中我们经常遇到竖排的日语&#xff0c;有时候我们用普通的日语识别的软件根本无法完成 这个时候我们就需要一款可以识别竖排的日语工具&#xff0c;横排的我们很容易就能找到&#xff0c;但是竖排的就无能为力了 今天我们讲下如何识别竖排日语识别&a…