【网络爬虫】(1) 网络请求,urllib库介绍

news2024/11/23 19:09:23

各位同学好,今天开始和各位分享一下python网络爬虫技巧,从基本的函数开始,到项目实战。那我们开始吧。

1. 基本概念

这里简单介绍一下后续学习中需要掌握的概念。

(1)http 和 https 协议。http是超文本传输,接收HTML页面的方法,服务器80端口。https是http协议的加密版本,服务端口是443端口。 

(2)URL 统一资源定位符。形如:scheme://host:port/path/?query-string=xxx#anchor

 https://www.bilibili.com/video/BV1eT4y1Z7NB?p=3 为例

scheme:访问协议,一般为 http 或 https。

host:主机名,域名。上面的 www.bilibili.com

path:查找路径。video/BV1eT4y1Z7NB 就是 path

port:端口号,访问网站时浏览器默认 80 端口

query-string:查询字符串。如上面的 ?p=3,如有多个,用&分隔

anchor:锚点。后台不用管,是前端用来做页面定位的。相当于现在停留的位置是网页的第几个小节。

注:在浏览器中请求一个url,浏览器会对url进行编码。除英文字母,数字和部分符号外,其他全部使用百分号和十六进制码值进行编码。中文字词需要重新编码后再发送给服务器

(3)常用的请求方法

GET 请求。只从服务器获取数据下来(下载文件),并不会对服务器资源产生任何影响的时候使用GET请求。

POST 请求。向服务器发送数据(登录),上传文件等,会对服务器资源产生影响时使用POST请求


2. urllib 库

urllib 库是 python3 中自带的网络请求库,可以模拟浏览器的行为,向服务器发送一个请求,并可以保存服务器返回的数据。

2.1 urlopen 函数

用于打开一个远程的 url 连接,并且向这个连接发出请求,获取响应结果。返回的结果是一个 https 响应对象,这个响应对象中记录了本次 https 访问的响应头和响应体。

使用方法为:

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

参数:

url: 需要打开的网址

data:字节流编码格式,可以用 urllib.parse.urlencode() bytes() 方法转换参数格式,如果要设置了data参数,则请求方式为POST

timeout: 设置网站的访问超时时间,单位:秒。若不指定,则使用全局默认时间。若请求超时,则会抛出urllib.error.URLError异常。

返回值:

http.client.HTTPResponse对象: 返回类文件句柄对象,有read(size),readline,readlines,getcode方法。read(size)若不指定size,则全部读出来。readline读取第一行。readlines返回值以多行的形式读出来。

getcode(): 获取响应状态。返回200,表示请求成功,返回404,表示网址未找到。

geturl(): 返回请求的url。

from urllib import request

# 打开网站,返回响应对象resp
resp = request.urlopen('https://www.baidu.com')

# 通过.read()读取这个网页的源代码,相当于在百度页面右键检查
print(resp.read())
# 返回网页信息

print(resp.getcode())  #状态码
# 200

resp.read() 返回类似如下信息,这里只显示部分

b'<html>\r\n<head>\r\n\t<script>\r\n\t\tlocation.replace(location.href.replace("https://","http://"));
\r\n\t</script>\r\n</head>\r\n<body>\r\n\t<noscript><meta http-equiv="refresh" content="0;
url=http://www.baidu.com/"></noscript>\r\n</body>\r\n</html>'

2.2 urlretrieve 函数

直接将远程数据下载到本地,方法如下:

rlretrieve(url, filename=None, reporthook=None, data=None)

参数:

url:下载链接地址

filename:指定了保存本地路径,若参数未指定,urllib 会生成一个临时文件保存数据。

reporthook:是一个回调函数,当连接上服务器、以及相应的数据块传输完毕时会触发该回调,我们可以利用这个回调函数来显示当前的下载进度。

data:指 POST 导服务器的数据,该方法返回一个包含两个元素的( filename,headers ) 元组,filename 表示保存到本地的路径,header 表示服务器的响应头

# 将百度的首页下载到本地
from urllib import request

# 下载某一张图片,传入图像的url和保存路径
request.urlretrieve('https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fnimg.ws.126.net%2F%3Furl%3Dhttp%253A%252F%252Fdingyue.ws.126.net%252F2021%252F1010%252F90f82dafj00r0q72d001jc000hs009uc.jpg%26thumbnail%3D650x2147483647%26quality%3D80%26type%3Djpg&refer=http%3A%2F%2Fnimg.ws.126.net&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1642840179&t=888aee0d4f561d7238b290c9da876362', 
                    'C:/Users/admin/Documents/Downloads/test1.jpg')

# 下载成功后返回:
('C:/Users/admin/Documents/Downloads/test1.jpg',
 <http.client.HTTPMessage at 0x26b86c85a60>)

2.3 urlencode 函数

浏览器发送请求时,如果 url 中包含了中文或其他特殊字符,那么浏览器会自动进行编码

如果使用代码发送请求,必须手动进行编码,这时需要 urlencode 函数实现。urlencode 把字典数据转换为url编码的数据

方法如下:

urllib.parse.urlencode( 字典 )

下面,对张三使用%和十六进制重新编码,键和键之间使用&号连接,空格使用+号连接

from urllib import parse
# 自定义一个字典,后续用于重新编码
params = {'name':'张三','age':18, 'greet':'hello world'}
# 对字典编码
result = parse.urlencode(params)
print(result)
# 除英文和数字外都使用 %号和十六进制来编码

# 打印结果
name=%E5%BC%A0%E4%B8%89&age=18&greet=hello+world

实际使用:

如果网址中有中文,需要先将中文从中分割出来,以字典的方式重新编码转换后,再拼接到网址中。

from urllib import parse

# url = 'https://www.baidu.com/s?wd=周杰伦'  # 直接用于网络请求时,ascii码不能识别

# 使用方法
url = 'https://www.baidu.com/s'

# 定义一个字典
params = {'wd':'周杰伦'}
# 对中文编码
qs = parse.urlencode(params)
print(qs)  #打印编码结果

# 拼接到网址url后面
url = url + '?' + qs
print(url)

# 网络请求,得到网页中的数据
resp = request.urlopen(url)
print(resp.read())

打印结果分别为

wd=%E5%91%A8%E6%9D%B0%E4%BC%A6

https://www.baidu.com/s?wd=%E5%91%A8%E6%9D%B0%E4%BC%A6

b'<html>\r\n<head>\r\n\t<script>\r\n\t\tlocation.replace(location.href.replace("https://","http://"));
\r\n\t</script>\r\n</head>\r\n<body>\r\n\t<noscript><meta http-equiv="refresh" content="0;
url=http://www.baidu.com/"></noscript>\r\n</body>\r\n</html>'

2.4 parse_qs 函数

将经过编码后的 url 参数解码,返回字典类型,方法如下:

urllib.parse.urlencode( url )

应用:

from urllib import parse

# 先对中文进行编码
params = {'name:':'张三','age':18,'greet':'hello world'}
qs = parse.urlencode(params)
print('编码后:',qs)

# 对编码后的结果解码
result = parse.parse_qs(qs)
print('解码后:', result)

打印结果如下:

编码后: name%3A=%E5%BC%A0%E4%B8%89&age=18&greet=hello+world

解码后: {'name:': ['张三'], 'age': ['18'], 'greet': ['hello world']}

2.4 urlparse 和 urlsplit 函数

分割 url 中的各个组成部分,分割成 scheme,host,path,params,query-string,anchor,具体含义看最上面。

这两个函数的区别是:urlsplit 不返回 params,但是这个参数params基本用不到。

(1)urlparse 方法

urllib.parse.urlparse(urlstring, scheme='', allow_fragments=True)

urlstring: 待解析的URL,必填项

scheme: 默认的协议,如 http 或 https 等。

allow_fragments: 即是否忽略fragment。若设为 False,fragment 部分就会被忽略,它会被解析为 path、parameters 或 query 的一部分,而 fragment 部分为空。

返回值为所有分割后的结果

# 使用 urlparse 方法

from urllib import parse

# 给出一个url网址
url = 'https://blog.csdn.net/dgvv4?spm=1001.5501#1'

# 使用 urlparse 解析分割 url 中的组成部分
result = parse.urlparse(url)

print(result)  # 获取所有属性

print('scheme:', result.scheme) # 获取指定属性

返回值如下:

ParseResult(scheme='https', netloc='blog.csdn.net', path='/dgvv4', params='', query='spm=1001.5501', fragment='1')

scheme: https

(2)urlsplit 方法

# 使用 urlsplit 方法

from urllib import parse

# 给出一个url网址
url = 'https://blog.csdn.net/dgvv4?spm=1001.5501#1'

# 使用 urlparse 解析分割 url 中的组成部分
result = parse.urlsplit(url)

print(result)

print('scheme:', result.scheme)

返回值如下,返回结果没有params参数

SplitResult(scheme='https', netloc='blog.csdn.net', path='/dgvv4', query='spm=1001.5501', fragment='1')

scheme: https

2.5 Request 函数

如果在请求时增加一些请求头,防止网页发现是爬虫,避免爬虫失败。那么就必须使用resquest.Resquest() 类来实现。比如要增加一个User-Agent。

from urllib import request, parse

# 输入请求
url = 'http://www.acga......com/'

# 输入浏览器页面的User-Agent请求头,使请求头更加像这个浏览器
headers = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36 Edg/96.0.1054.62',
           'Refer':'http://www.acganime.com/'}

# data需要经过urlencode重新编码后才能传进去
data = {
    'first' : True,
    'pn' : 1, #第几页
    'kd' : 'cos' }
# 重新编码
data = parse.urlencode(data)
# 编码类型转换成utf-8
data = data.encode('utf-8')

# 使用request.Request,添加请求头,只是定义好了一个类,并没有发送请求
req = request.Request(url, headers=headers, data=data, method='POST') #请求方式为get   

# 使用 urlopen 方法获取网页信息
resp = request.urlopen(req)  #传入添加请求头后的类
print(resp.read().decode('utf-8')) # 转换成utf-8显示结果

返回爬取的网页数据:

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
    <meta name="renderer" content="webkit">
<!--     <meta name="referrer" content="no-referrer" /> -->
    <meta name="viewport" content="initial-scale=1.0,maximum-scale=5,width=device-width,viewport-fit=cover">
.........................................................

推广,发起网络请求的计算机的IP地址,可从如下活动获得:

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

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

相关文章

【考研数学二】线性代数重点笔记

目录 第一章 行列式 1.1 行列式的几何意义 1.2 什么是线性相关&#xff0c;线性无关 1.3 行列式几何意义 1.4 行列式求和 1.5 行列式其他性质 1.6 余子式 1.7 对角线行列式 1.8 分块行列式 1.9 范德蒙德行列式 1.10 爪形行列式的计算 第二章 矩阵 2.1 初识矩阵 2…

基于nodejs+vue企业人才引进服务平台python-flask-django-php

本文通过采用MySQL数据库以及nodejs语言、express框架&#xff0c;结合国内线上管理现状&#xff0c;开发了一个基于node的企业人才引进服务平台。系统分为多个功能模块&#xff1a;用户信息、企业信息、招聘信息、应聘信息等。通过系统测试&#xff0c;本系统实现了系统设计目…

ffmpeg拉流并解码

流程 注意事项 版本不同导致的api差异资源安全释放

C# 将 Word 转文本存储到数据库并进行管理

目录 前言 1. 创建数据库表格 2. 安装必需的 NuGet 包 3. 转换 Word 文档为文本 4. 将文本存储到数据库 5. 完整示例 前言 C# 是一种通用的编程语言&#xff0c;可以用于开发各种类型的应用程序&#xff0c;包括处理文本和数据库管理。在这篇文章中&#xff0c;我将向您…

10.2024

使用选择排序将{2,9,5,0,1,3,6,8}排序 代码&#xff1a; public class 第十题 {public static void main(String[] args) {int a[]{2,9,5,0,1,3,6,8};int begin0;int enda.length-1;while (begin<end){int mina[begin];int tbegin;for (int ibegin;i<end;i){if(min>…

瑞吉外卖实战学习--完善登录功能

完善登录功能 1、创建自定义过滤器LoginCheckFiler1.1通过WebFilter创建过滤器1.2 验证是否可以拦截请求1.3 代码 2、在启动类加入注解ServletComponentScan 用来扫描过滤器触发所有的过滤器ServletComponentScan 3、完善过滤器的处理逻辑3.1判断是否需要是要放行的请求3.2判断…

基于nodejs+vue考研互助交流系统python-flask-django-php

同时还能为用户提供一个方便实用的考研互助交流系统&#xff0c;使得用户能够及时地找到合适自己的考研信息。管理员在使用本系统时&#xff0c;可以通过后台管理员界面管理用户的信息&#xff0c;也可以发布系统公告&#xff0c;让用户及时了解考研信息。这样&#xff0c;用户…

javaSwing超级玛丽游戏

一、摘要 摘要 近年来&#xff0c;Java作为一种新的编程语言&#xff0c;以其简单性、可移植性和平台无关性等优点&#xff0c;得到了广泛地应用。J2SE称为Java标准版或Java标准平台。J2SE提供了标准的SDK开发平台。利用该平台可以开发Java桌面应用程序和低端的服务器应用程序…

EPSON推出RX8804CE为工业机器提供稳定且精准的时钟信号

工业机器是智能工厂的关键主体组成部分&#xff0c;工业机器的时钟稳定性和精确性直接关系到整个系统的生产高效性和稳定性。EPSON推出了面向工业机器、手持设备、室外机等领域的实时时钟模块RX8804CE&#xff0c;可选择32.768 KHz、1024 Hz、1 Hz三种频率输出&#xff0c;温度…

Android视角看鸿蒙第九课-鸿蒙的布局

鸿蒙的四大布局 导读 前面八篇文章描述了鸿蒙app的配置文件&#xff0c;关于版本号&#xff0c;开发版本&#xff0c;桌面图标等等配置方式。从这一篇文章开始学习鸿蒙的UI使用方式。 前面我们学习到鸿蒙有ability和page的区分&#xff0c;ability类似Activity但又不完全一样…

获取高德安全码SHA1

高德开发者平台上给的三种方法 获取安全码SHA1&#xff0c;这里我自己使用的是第三种方法。 1、通过Eclipse编译器获取SHA1 使用 adt 22 以上版本&#xff0c;可以在 eclipse 中直接查看。 Windows&#xff1a;依次在 eclipse 中打开 Window -> Preferances -> Androi…

8节点空间壳单元Matlab有限元编程 | 曲壳单元 | 模态分析 | 3D壳单元 | 板壳理论| 【源代码+理论文本】

专栏导读 作者简介&#xff1a;工学博士&#xff0c;高级工程师&#xff0c;专注于工业软件算法研究本文已收录于专栏&#xff1a;《有限元编程从入门到精通》本专栏旨在提供 1.以案例的形式讲解各类有限元问题的程序实现&#xff0c;并提供所有案例完整源码&#xff1b;2.单元…

如何安全地添加液氮到液氮罐中

液氮是一种极低温的液体&#xff0c;它在许多领域广泛应用&#xff0c;但在处理液氮时需谨慎小心。添加液氮到液氮罐中是一个常见的操作&#xff0c;需要遵循一些安全准则以确保操作人员的安全和设备的完整性。 选择合适的液氮容器 选用专业设计用于存储液氮的容器至关重要。…

选择最佳图像处理工具OpenCV、JAI、ImageJ、Thumbnailator和Graphics2D

文章目录 1、前言2、 图像处理工具效果对比2.1 Graphics2D实现2.2 Thumbnailator实现2.3 ImageJ实现2.4 JAI&#xff08;Java Advanced Imaging&#xff09;实现2.5 OpenCV实现 3、图像处理工具结果 1、前言 SVD(stable video diffusion)开放了图生视频的API&#xff0c;但是限…

CI/CD实战-jenkins结合docker 5

实验准备&#xff1a; 在docker主机要下载git工具 禁掉key的校验 确保在立即构建项目时不会出现任何报错&#xff1a; 自动化构建docker镜像 在server3上安装docker-ce 修改内核参数 拷贝证书 添加默认仓库 添加harbor仓库的解析 测试拉取 登录harbor私有仓库 在jenkins安装d…

WPF使用外部字体,思源黑体,为例子

1.在工程中新建文件夹&#xff0c;命名为“Font"。 2.将下载好的字体文件复制到Font文件夹。 3.在工程中&#xff0c;加入静态资源 <Window.Resources><FontFamily x:Key"SYBold">/AnalyzeImage;Component/Font/#思源黑体 CN Bold</FontFamily…

k8s的单pod单ip网络模型

背景 在k8s中&#xff0c;不再是每个docker容器一个ip地址&#xff0c;而是每个pod一个ip地址&#xff0c;docker容器只是pod里面的其中一个进程&#xff0c;可能拥有对外的端口号&#xff0c;但是不在为docker容器单独分配ip地址&#xff0c;pod里面的容器共享pod的ip地址 单…

解決flask-restful提示Did not attempt to load JSON data 问题

在使用flask-restfull进行API开发的时候。一旦我使用类似下面的代码从url或者form中获得参数就会出现报错&#xff1a;Did not attempt to load JSON data because the request Content-Type was not ‘application/json’。 代码如下&#xff1a; # Flask_RESTFUl数据解析 f…

2024-03-25 作业

作业要求&#xff1a; 整理思维导图定义自己的命名空间&#xff0c;其中有string类型的变量&#xff0c;再定义两个函数&#xff0c;一个函数完成字符串的输入&#xff0c;一个函数完成求字符串长度&#xff0c;再定义一个全局函数完成对该字符串的反转有以下定义&#xff0c;说…

ESCTF-Web赛题WP

0x01-初次见面-怦然心动:your name? 随便输入一个字 根据提示可以看到 我们需要看源代码 直接 搜索 secret 关键字或者 ESCTF flag ESCTF{K1t0_iS_S0_HAPPy} 0x02-小k的请求 更安全的传参 post 参数为ESCTF 值为 love 自己的ip 同时还有个要求 是需要从度娘转过来 https://www…