Python 爬虫入门(六):urllib库的使用方法
Python 爬虫入门(六):urllib库的使用方法
- 前言
- 1. urllib 概述
- 2. urllib.request 模块
- 2.1 发送GET请求
- 2.2 发送POST请求
- 2.3 添加headers
- 2.4 处理异常
- 3. urllib.error 模块
- 4. urllib.parse 模块
- 4.1 URL解析
- 4.2 URL编码和解码
- 4.3 拼接URL
- 5. urllib.robotparser 模块
- 6. 实战示例: 爬取豆瓣电影Top250
- 7. urllib vs requests
- 8. 注意事项
- 总结
前言
- 欢迎来到"Python 爬虫入门"系列的第六篇文章。今天我们来学习Python标准库中的urllib,这是一个用于处理URL的强大工具包。
- urllib是Python内置的HTTP请求库,不需要额外安装,就可以直接使用。它提供了一系列用于操作URL的函数和类,可以用来发送请求、处理响应、解析URL等。尽管现在很多人更喜欢使用requests库,但是了解和掌握urllib仍然很有必要,因为它是很多其他库的基础,而且在一些特殊情况下可能会更有优势。
- 在这篇文章里,我会详细介绍urllib的四个主要模块:request、error、parse和robotparser,并通过实际的代码示例来展示它们的用法。
1. urllib 概述
urllib是 Python 标准库中用于URL处理的模块集合,不需要通过 pip 安装。
它包含了多个处理URL的模块:
- urllib.request: 用于打开和读取URL
- urllib.error: 包含urllib.request抛出的异常
- urllib.parse: 用于解析URL
- urllib.robotparser: 用于解析robots.txt文件
这些模块提供了一系列强大的工具,可以帮助我们进行网络请求和URL处理。接下来,我们将逐一介绍这些模块的主要功能和使用方法。
2. urllib.request 模块
urllib.request模块是urllib中最常用的模块,它提供了一系列函数和类来打开URL(主要是HTTP)。
我们可以使用这个模块来模拟浏览器发送GET和POST请求。
2.1 发送GET请求
使用urllib.request发送GET请求非常简单,我们可以使用urlopen()函数:
import urllib.request
import gzip
import iourl = 'https://www.python.org/'
response = urllib.request.urlopen(url)# 获取响应头
content_type = response.headers.get('Content-Encoding')# 读取数据
data = response.read()# 检查是否需要解压缩
if content_type == 'gzip':buf = io.BytesIO(data)with gzip.GzipFile(fileobj=buf) as f:data = f.read()print(data.decode('utf-8'))
这段代码会打开Python官网,并打印出网页的HTML内容。
2.2 发送POST请求
发送POST请求稍微复杂一些,我们需要使用Request对象:
import urllib.request
import urllib.parseurl = 'http://httpbin.org/post'
data = urllib.parse.urlencode({'name': 'John', 'age': 25}).encode('utf-8')
req = urllib.request.Request(url, data=data, method='POST')
response = urllib.request.urlopen(req)print(response.read().decode('utf-8'))
这段代码向httpbin.org发送了一个POST请求,包含了name和age两个参数。
2.3 添加headers
在实际的爬虫中,我们常常需要添加headers来模拟浏览器行为。
可以在创建Request对象时添加headers:
import urllib.request
import gzip
import iourl = 'https://www.python.org/'
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'
}
req = urllib.request.Request(url, headers=headers)
response = urllib.request.urlopen(req)# 获取响应头中的 Content-Encoding
content_encoding = response.headers.get('Content-Encoding')# 读取数据
data = response.read()# 如果数据被 gzip 压缩,则需要解压
if content_encoding == 'gzip':buf = io.BytesIO(data)with gzip.GzipFile(fileobj=buf) as f:data = f.read()# 尝试使用 'utf-8' 解码
try:print(data.decode('utf-8'))
except UnicodeDecodeError:print("Cannot decode data with 'utf-8' encoding.")
添加headers后,运行结果如下:
2.4 处理异常
在进行网络请求时,可能会遇到各种异常情况。我们可以使用try-except语句来处理这些异常:
import urllib.request
import urllib.error
import gzip
import iotry:# 发送请求并获取响应response = urllib.request.urlopen('https://www.python.org/')# 获取响应头中的 Content-Encodingcontent_encoding = response.headers.get('Content-Encoding')# 读取数据data = response.read()# 如果数据被 gzip 压缩,则需要解压if content_encoding == 'gzip':buf = io.BytesIO(data)with gzip.GzipFile(fileobj=buf) as f:data = f.read()# 尝试使用 'utf-8' 解码print(data.decode('utf-8'))
except urllib.error.URLError as e:print(f'URLError: {e.reason}')
except urllib.error.HTTPError as e:print(f'HTTPError: {e.code}, {e.reason}')
except UnicodeDecodeError:print("Cannot decode data with 'utf-8' encoding.")
这段代码会捕获URLError和HTTPError,这两种异常都定义在urllib.error模块中。
3. urllib.error 模块
urllib.error模块定义了urllib.request可能抛出的异常类。主要有两个异常类:
- URLError: 由urllib.request产生的异常的基类。
- HTTPError: URLError的子类,用于处理HTTP和HTTPS URL的错误。
我们已经在上面的例子中看到了如何捕获和处理这些异常。
4. urllib.parse 模块
urllib.parse模块提供了许多URL处理的实用函数,例如解析、引用、拆分和组合。
4.1 URL解析
from urllib.parse import urlparseurl = 'https://www.python.org/doc/?page=1#introduction'
parsed = urlparse(url)print(parsed)
print(f'Scheme: {parsed.scheme}')
print(f'Netloc: {parsed.netloc}')
print(f'Path: {parsed.path}')
print(f'Params: {parsed.params}')
print(f'Query: {parsed.query}')
print(f'Fragment: {parsed.fragment}')
这段代码会解析URL,并打印出各个组成部分。
4.2 URL编码和解码
在处理URL时,我们经常需要对参数进行编码和解码:
from urllib.parse import urlencode, unquoteparams = {'name': 'John Doe', 'age': 30, 'city': 'New York'}
encoded = urlencode(params)
print(f'Encoded: {encoded}')decoded = unquote(encoded)
print(f'Decoded: {decoded}')
urlencode()函数将字典转换为URL编码的字符串,而unquote()函数则进行解码。
4.3 拼接URL
from urllib.parse import urljoinbase_url = 'https://www.python.org/doc/'
relative_url = 'tutorial/index.html'
full_url = urljoin(base_url, relative_url)print(full_url)
urljoin()函数可以方便地将一个基础URL和相对URL拼接成一个完整的URL。
5. urllib.robotparser 模块
urllib.robotparser模块提供了一个RobotFileParser类,用于解析robots.txt文件。
robots.txt是一个网站用来告诉爬虫哪些页面可以爬取,哪些不可以爬取的文件。
from urllib.robotparser import RobotFileParserrp = RobotFileParser()
rp.set_url('https://www.python.org/robots.txt')
rp.read()print(rp.can_fetch('*', 'https://www.python.org/'))
print(rp.can_fetch('*', 'https://www.python.org/admin/'))
这段代码会读取Python官网的robots.txt文件,然后检查是否允许爬取某些URL。
6. 实战示例: 爬取豆瓣电影Top250
现在,让我们用我们学到的知识来写一个实际的爬虫,爬取豆瓣电影Top250的信息。
import urllib.request
import urllib.error
import re
from bs4 import BeautifulSoupdef get_movie_info(url):headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'}try:req = urllib.request.Request(url, headers=headers)response = urllib.request.urlopen(req)html = response.read().decode('utf-8')soup = BeautifulSoup(html, 'html.parser')movie_list = soup.find('ol', class_='grid_view')for movie_li in movie_list.find_all('li'):rank = movie_li.find('em').stringtitle = movie_li.find('span', class_='title').stringrating = movie_li.find('span', class_='rating_num').stringif movie_li.find('span', class_='inq'):quote = movie_li.find('span', class_='inq').stringelse:quote = "N/A"print(f"Rank: {rank}")print(f"Title: {title}")print(f"Rating: {rating}")print(f"Quote: {quote}")print('-' * 50)except urllib.error.URLError as e:if hasattr(e, 'reason'):print(f'Failed to reach the server. Reason: {e.reason}')elif hasattr(e, 'code'):print(f'The server couldn\'t fulfill the request. Error code: {e.code}')# 爬取前5页
for i in range(5):url = f'https://movie.douban.com/top250?start={i*25}'get_movie_info(url)
这个爬虫会爬取豆瓣电影Top250的前5页,每页25部电影,共125部电影的信息。它使用了我们之前学到的urllib.request发送请求,使用BeautifulSoup解析HTML,并处理了可能出现的异常。
7. urllib vs requests
虽然urllib是Python的标准库,但在实际开发中,很多人更喜欢使用requests库。
这是因为:
- 易用性: requests的API设计更加人性化,使用起来更加直观和简单。
- 功能强大: requests自动处理了很多urllib需要手动处理的事情,比如保持会话、处理cookies等。
- 异常处理: requests的异常处理更加直观和统一。
然而,urllib作为标准库仍然有其优势:
- 无需安装: 作为标准库,urllib无需额外安装即可使用。
- 底层操作: urllib提供了更多的底层操作,在某些特殊情况下可能更有优势。
在大多数情况下,如果你的项目允许使用第三方库,requests可能是更好的选择。但了解和掌握urllib仍然很有必要,因为它是Python网络编程的基础,而且在一些特殊情况下可能会更有用。
8. 注意事项
在使用urllib进行爬虫时,有一些重要的注意事项:
- 遵守robots.txt: 使用urllib.robotparser解析robots.txt文件,遵守网站的爬取规则。
- 添加合适的User-Agent: 在headers中添加合适的User-Agent,避免被网站识别为爬虫而被封禁。
- 控制爬取速度: 添加适当的延时,避免对目标网站造成过大压力。
- 处理异常: 正确处理可能出现的网络异常和HTTP错误。
- 解码响应: 注意正确解码响应内容,处理不同的字符编码。
- URL编码: 在构造URL时,注意对参数进行正确的URL编码。
总结
-
在本文中,我们学习了Python标准库urllib的使用方法,包括发送GET和POST请求、异常处理、URL解析和构造,以及robots.txt文件解析,并将这些知识应用到了实际的爬虫案例中。
-
虽然requests库在实际开发中更受欢迎,但掌握urllib仍然十分重要。它不仅是Python网络编程的基础,而且在某些特殊情况下可能会更有优势。
-
希望通过本文,你对urllib有了更深入的理解,并能在你的爬虫项目中灵活运用。无论使用何种工具,都要遵守网络爬虫的伦理规范,尊重网站的规则和其他用户的权益。
如果你有任何问题或者好的想法,欢迎随时和我交流。
相关文章:

Python 爬虫入门(六):urllib库的使用方法
Python 爬虫入门(六):urllib库的使用方法 前言1. urllib 概述2. urllib.request 模块2.1 发送GET请求2.2 发送POST请求2.3 添加headers2.4 处理异常 3. urllib.error 模块4. urllib.parse 模块4.1 URL解析4.2 URL编码和解码4.3 拼接URL 5. ur…...

个人开发神器,一应俱全,有你想要的!
哈喽,各位小伙伴们好,我是给大家带来各类黑科技与前沿资讯的小武。 经常有很多小伙伴问小武,是从哪里获取到这么多资源,其实除了熟知的吾爱、酷安等知名论坛集聚地,还有一些强大的资源聚合类软件也非常重要。 如之前安…...
电子电气架构 --- SOVD在域控制器的应用
我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 屏蔽力是信息过载时代一个人的特殊竞争力,任何消耗你的人和事,多看一眼都是你的不对。非必要不费力证明自己,无利益不试图说服别人,是精神上的节…...

React(四):DOCX文件在线预览
效果 注意 ⚠️注意:部分文件预览存在问题 依赖 $ yarn add docx-preview $ yarn add jszip源码 import ./index.scss; import {useRef} from react; import type {UploadRequestOption} from rc-upload/lib/interface; import {Upload, Button, message} from an…...

Java IO.字符集,流,缓冲流 转换流 对象操作流
一.字符集 如果使用字节流 , 把文本文件中的内容读取到内存时, 可能会出现乱码 如果使用字节流 , 把中文写入文本文件中 , 也有可能会出现乱码 读取n.txt"你好" 两个汉字 字节流读中文,每次只能读一部分所以出现了乱码 字符集(Character se…...

线性稳压器的内部电路与构成分析
线性稳压器的一般的引脚构成 线性稳压器基本上由VIN (输入)、VO (输出)、GND (接地)三个引脚构成。在输出可变的线性稳压器上添加了用于反馈输出电压的FB(反馈引脚)。 简单来说&am…...

Go语言实现多协程文件下载器
文章目录 前言流程图主函数下载文件初始化分片下载worker分发下载任务获取下载文件的大小下载文件分片错误重试项目演示最后 前言 你好,我是醉墨居士,最近在开发文件传输相关的项目,然后顺手写了一个多协程文件下载器,代码非常精…...
本地方法详解
本地方法(Native Methods)是指那些由Java程序调用,但其实现是用非Java语言(如C、C等)编写的方法。它们通常用于访问操作系统底层的功能或进行高效的计算,这些是Java本身不能直接实现的。下面详细解释本地方…...
每日新闻掌握【2024年8月3日 星期六】
2024年8月3日 星期六 农历六月廿九 大公司/大事件 微信地震预警全国上线 36氪获悉,国家地震烈度速报与预警工程已于7月25日正式通过国家验收。8月2日,在中国地震局指导下,中国地震台网中心、中央广播电视总台国家应急广播与腾讯联合推出“中…...

python入门基础篇(一)
基础篇 Python基础安装与配置Python环境理解Python解释器第一个Python程序:"Hello, World!" 基础语法注释与文档字符串变量与数据类型数字类型:整数、浮点数、复数字符串布尔值None值 运算符算术运算符比较运算符逻辑运算符赋值运算符位运算符…...

windows下在线预览服务kkFileView4.4.0问题记录
前几天找到一个开源项目:kkFileView,感觉可能以后可能会用到,所以尝试了下。 通过git下载下来,版本是4.4.0,通过idea打开项目,发现老是无法找到组件aspose-cad,版本是23.9. 找了好多文章&#x…...
Java:通过反射获取class类的属性
有如下一个普通类,我想获取他的所有属性值 package com.demo.bean;import lombok.Data;import java.util.List;Data public class UserBean {private String name;private Integer age;private List<String> tags; }可以通过反射的方式获取属性值 package c…...

07.FreeRTOS列表与列表项
文章目录 07. FreeRTOS列表与列表项1. 列表和列表项的简介2. 列表相关API函数3. 代码验证 07. FreeRTOS列表与列表项 1. 列表和列表项的简介 列表的定义: typedef struct xLIST {listFIRST_LIST_INTEGRITY_CHECK_VALUE /* 校验值 */volatile UBaseType_t uxN…...
餐饮业油烟净化器安装势在必行,切勿侥幸
我最近分析了餐饮市场的油烟净化器等产品报告,解决了餐饮业厨房油腻的难题,更加方便了在餐饮业和商业场所有需求的小伙伴们。 随着环保法规的日益严格和公众环保意识的提升,餐饮业油烟排放问题成为社会关注的焦点。油烟不仅影响环境质量&am…...

SpringBoot集成阿里百炼大模型 原子的学习日记Day01
文章目录 概要下一章SpringBoot集成阿里百炼大模型(多轮对话) 原子的学习日记Day02 整体架构流程技术名词解释集成步骤1,选择大模型以及获取自己的api-key(前面还有一步开通服务就没有展示啦!)2,…...

【网络编程】网络原理(一)
系列文章目录 1、 初识网络 2、网络编程的基础使用(一) 文章目录 系列文章目录前言一、端口号的使用二、UDP报文学习1.报文格式2.MD5算法 总结 前言 在前文中,主要对UDP和TCP协议有了简单的了解,而这两种协议是负责传输层的内容…...

鲁班上门维修安装系统源码开发之功能模式
鲁班上门维修安装系统在当今的趋势呈现出显著的增长与创新。随着物联网、智能家居的普及,以及消费者对便捷、高效生活方式的追求,鲁班上门维修安装系统凭借其多渠道预约、智能派单、在线支付与费用明细透明等优势,赢得了市场的广泛认可。 …...
图数据处理的新时代:阿里FraphCompute与蚂蚁金服TuGraph对比综述
目录 前言 阿里FraphCompute与蚂蚁金服TuGraph的主要特性和功能的比较: 阿里FraphCompute与蚂蚁金服TuGraph在不同应用场景分析对比: 阿里FraphCompute与蚂蚁金服TuGraph未来趋势的对比: FraphCompute与TuGraph详解 缺点劣势深入比较 前言…...

InnoDB引擎下SQL的执行流程
SQL执行流程 连接器 客户端连接驱动与mysql连接池连接 半双工通信传入客户端的sql 查询缓存(8.0之后没有) 删除原因 如果每次查询条件不同导致命中率低没有命中缓存 创建新缓存在创建缓存的时候会添加表级锁缓存更新需要批量失效 sql解析器 对传入的sql 词法分析 分解成各种t…...
Java小白入门到实战应用教程-重写和重载
引言 在上一节中我们学习了面向对象中的继承,然后在那一节中我们提到了一个知识点叫做:重写。 通过上节的代码样例我们也观察到了,重写是发生在子类和父类的这种继承关系中。 继承的特点就是提取所有子类共有的属性和方法,但是…...

JavaSec-RCE
简介 RCE(Remote Code Execution),可以分为:命令注入(Command Injection)、代码注入(Code Injection) 代码注入 1.漏洞场景:Groovy代码注入 Groovy是一种基于JVM的动态语言,语法简洁,支持闭包、动态类型和Java互操作性,…...
Java 8 Stream API 入门到实践详解
一、告别 for 循环! 传统痛点: Java 8 之前,集合操作离不开冗长的 for 循环和匿名类。例如,过滤列表中的偶数: List<Integer> list Arrays.asList(1, 2, 3, 4, 5); List<Integer> evens new ArrayList…...

【大模型RAG】Docker 一键部署 Milvus 完整攻略
本文概要 Milvus 2.5 Stand-alone 版可通过 Docker 在几分钟内完成安装;只需暴露 19530(gRPC)与 9091(HTTP/WebUI)两个端口,即可让本地电脑通过 PyMilvus 或浏览器访问远程 Linux 服务器上的 Milvus。下面…...

【CSS position 属性】static、relative、fixed、absolute 、sticky详细介绍,多层嵌套定位示例
文章目录 ★ position 的五种类型及基本用法 ★ 一、position 属性概述 二、position 的五种类型详解(初学者版) 1. static(默认值) 2. relative(相对定位) 3. absolute(绝对定位) 4. fixed(固定定位) 5. sticky(粘性定位) 三、定位元素的层级关系(z-i…...
五年级数学知识边界总结思考-下册
目录 一、背景二、过程1.观察物体小学五年级下册“观察物体”知识点详解:由来、作用与意义**一、知识点核心内容****二、知识点的由来:从生活实践到数学抽象****三、知识的作用:解决实际问题的工具****四、学习的意义:培养核心素养…...

1.3 VSCode安装与环境配置
进入网址Visual Studio Code - Code Editing. Redefined下载.deb文件,然后打开终端,进入下载文件夹,键入命令 sudo dpkg -i code_1.100.3-1748872405_amd64.deb 在终端键入命令code即启动vscode 需要安装插件列表 1.Chinese简化 2.ros …...

DIY|Mac 搭建 ESP-IDF 开发环境及编译小智 AI
前一阵子在百度 AI 开发者大会上,看到基于小智 AI DIY 玩具的演示,感觉有点意思,想着自己也来试试。 如果只是想烧录现成的固件,乐鑫官方除了提供了 Windows 版本的 Flash 下载工具 之外,还提供了基于网页版的 ESP LA…...

视频字幕质量评估的大规模细粒度基准
大家读完觉得有帮助记得关注和点赞!!! 摘要 视频字幕在文本到视频生成任务中起着至关重要的作用,因为它们的质量直接影响所生成视频的语义连贯性和视觉保真度。尽管大型视觉-语言模型(VLMs)在字幕生成方面…...
【git】把本地更改提交远程新分支feature_g
创建并切换新分支 git checkout -b feature_g 添加并提交更改 git add . git commit -m “实现图片上传功能” 推送到远程 git push -u origin feature_g...
#Uniapp篇:chrome调试unapp适配
chrome调试设备----使用Android模拟机开发调试移动端页面 Chrome://inspect/#devices MuMu模拟器Edge浏览器:Android原生APP嵌入的H5页面元素定位 chrome://inspect/#devices uniapp单位适配 根路径下 postcss.config.js 需要装这些插件 “postcss”: “^8.5.…...