Python爬虫之urllib库

1、urllib库的介绍

可以实现HTTP请求,我们要做的就是指定请求的URL、请求头、请求体等信息

urllib库包含如下四个模块

  • request:基本的HTTP请求模块,可以模拟请求的发送。
  • error:异常处理模块。
  • parse:工具模块:如拆分、解析、合并
  • robotparse:主要用来识别网站的rebots.txt文件。(用的较少)

2、发送请求

2.1、urlopen

        urllib.request模块提供了基本的构造HTTP请求的方法,可以模拟浏览器的请求发起过程,同时还具有处理授权验证(Authentication)重定向(Redireaction)浏览器Cookie以及一些其他功能。

import urllib.requestresponse = urllib.request.urlopen('https://www.baidu.com')
print(response.read().decode('utf-8'))
print(type(response))	#输出响应的类型 HTTPResponse类型
print(response.status)	#输出响应的状态码 200
print(response.getheaders())	#输出响应的头信息
print(response.getheader('Server'))		#调用getheader方法,传参server得其值

2.1.1、data参数

        data参数是可选的。在添加该参数时,需要使用bytes方法将参数转化为字节流编码格式的内容,即bytes类型。如果传递了这个参数,那么它的请求方式就不再是GET,而是POST

import urllib.parse
import urllib.request# www.httpbin.org可以提供HTTP请求测试
data = bytes(urllib.parse.urlencode({'name':'germey'}),encoding='utf-8')
response = urllib.request.urlopen('https://www.httpbin.org/post',data=data)
print(response.read().decode('utf-8'))# {..."form":{"name":"germey"...}}表明是模拟表单提交
# 这里传递了一个参数name,值是germey,需要将其转码成bytes类型。转码时采用了bytes方法,该方法的第一个参数得是str类型,因此用urllib.parse模块李的urlencode方法将字典参数转化为字符串;第二个参数用于指定编码格式。

2.1.2、timeout参数

        timeout参数用于设置超时时间,单位为秒,意思是如果请求超出了设置的这个时间,还没有得到响应,就会抛出异常。如果不指定该参数,则会使用全局默认时间。这个参数支持HTTP、HTTPS、FTP请求。

import urllib.requestresponse = urllib.request.urlopen('https://www.httpbin.org/get',timeout=0.1)
print(response.read())# urllib.error.URLError: <urlopen error timed out> 超时
# 通过设置此超时时间,实现当一个网页长时间未响应时,跳过对它的抓取。

2.1.3、其他参数

  • context参数,该参数必须是ss1.SSLContext类型,用来指定SSL的设置。
  • cafilecapath这两个参数分别用来指定CA证书和其路径,这两个在请求HTTPS链接会有用
  • cadefault参数已经弃用,默认值为False

2.2、Request

        通过构造Request类型的对象,一方面可以将请求独立成一个对象,另一方面可更加丰富灵活的配置参数。

import urllib.requestrequest = urllib.request.Request('https://python.org')
response = urllib.request.urlopen(request)
print(response.read().decode('utf-8'))

         构造方法:

class urllib.request.Request(url,data=None,headers={},origin_req_host=None,unverifiable=False,method=None)
  • 第一个参数 url用于请求URL,这是必传参数,其他都是可选参数。
  • 第二个参数data如果要传参数,必须是bytes类型的。如果数据是字典,先用urllib.parse模块里的urlencode方法进行编码。
  • 第三个参数headers是一个字典这就是请求头,构造请求时,既可以通过headers参数直接狗仔此项,也可以通过调用请求实例的add_header方法添加。
  • 添加请求头最常见的方法就是修改User-Agent来伪装成浏览器。默认为Python-usrllib。若伪装成火狐浏览器,则设置User-Agent为:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36
  • 第四个参数origin_req_host值的是请求方的host名称或IP地址。
  • 第五个参数unverifiable表示请求是否是无法验证的,默认为False,意思是用户没有足够的权限来接受这个请求的结果。
  • 第六个参数method是一个字符串,用来指示请求使用的方法,例:GET、POST、PUT等。

2.3、高级用法

        各种处理器Handler。会有各种Handler子类继承BaseHandler类:

  • HTTPDefaultErrorHandler用来处理HTTP响应错误,所以错误类型都会抛出HTTPRrror类型的异常。
  • HTTPRedirectHandler用于处理重定向。
  • HTTPCookieProcessor用于处理Cookie。
  • ProxyHandler用于设置代理,代理默认为空。
  • HTTPPasswordMgr用于管理密码,它维护用户名密码对照表。
  • HTTPBasicAuthHandler用于管理认证,比如一个链接在打开时需要认证。

        另一个重要类OpenerDirector,简称opener、Opener类可以提供open方法。利用Handler类来构建Opener类。  

2.3.1、验证*

# 处理访问时需要用户名密码登录验证的方法。
from urllib.request import HTTPPasswordMgrWithDefaultRealm,HTTPBasicAuthHandler,build_opener
from urllib.error import URLErrorusername = 'admin'
password = 'admin'
url = 'https://ssr3.scrape.center/'p = HTTPPasswordMgrWithDefaultRealm()	
p.add_password(None,url,username,password)
auth_handler = HTTPBasicAuthHandler(p)	
opener = build_opener(auth_handler)try:result = opener.open(url)html = result.read().decode('utf-8')print(html)
except URLError as e:print(e.reason)# 首先实例化了一个HTTPBasicAuthHandler对象auth_handler,其参数是HTTPPasswordMgrWithDefaultRealm对象,它利用add_password方法添加用户名和密码。这样就建立了用来处理验证的Handler类。

2.3.2、代理*

# 添加代理
from urllib.error import URLError
from urllib.request import ProxyHandler,build_openerproxy_handler = ProxyHandler({'http':'http//127.0.0.1:8080','https':'https://127.0.0.1:8080'
})
opener = build_opener(proxy_handler)
try:response = opener.open('https://www.baidu.com')print(response.read().decode('utf-8'))
except URLError as e:print(e.reason)

2.3.3、Cookie*

# 1、获取网站的Cookie
import http.cookiejar,urllib.requestcookie = http.cookiejar.CookieJar()	# 声明Cookiejar对象,
handler = urllib.request.HTTPCookieProcessor(cookie)	# 构建一个handler
opener = urllib.request.build_opener(handler)	# 构建opener
response = opener.open('https://www.baidu.com')
for item in cookie:print(item.name + "=" + item.value) # 2、输出文件格式的内容cookie
import urllib.request,http.cookiejarfilename = 'cookie.txt'
cookie = http.cookiejar.MozillaCookieJar(filename)
# 若要保存LWP格式,修改为
cookie = http.cookiejar.LWPCookieJar(filename)handler = urllib.request.HTTPCookieProcessor(cookie)
opener = urllib.request.build_opener(handler)
response = opener.open('https://www.baidu.com')
cookie.save(ignore_discard=True,ignore_expires=True)# 3、读取内容、以LWP格式为例:
import urllib.request,http.cookiejarcookie = http.cookiejar.LWPCookieJar()
cookie.load('cookie.txt',ignore_discard=True,ignore_expires=True) # 获取cookie内容
handler = urllib.request.HTTPCookieProcessor(cookie) # 构建handler类和opener类
opener = urllib.request.build_opener(handler)
response = opener.open('https://www.baidu.com')
print(response.read().decode('utf-8'))

3、异常处理

        urllib库中的error模块定义了由request模块产生的异常。出现问题request则抛出error模块定义的异常。

3.1、URLError

        URLError类来自urllib库中的error模块,继承自OSError类,是error异常模块处理的基类,由request模块产生的异常都可以来处理。

        具有一个属性reason,返回错误的原因。

from urllib import request,error
try:response = request.urlopen('https://cuiqingcai.com/404')
except error.URLError as e:print(e.reason)		# Not Found
# 捕获异常,避免程序中止

3.2、HTTPError

        HTTPError是URLError的子类,专门来处理HTTP请求的错误,例如认证请求失败等,有三个属性:

  • code:返回HTTP状态码
  • reason:返回错误原因
  • headers返回请求头
from urllib import request,error
try:response = request.urlopen('https://cuiqingcai.com/404')
except error.HTTPError as e:print(e.reason,e.code,e.headers,sep='\n')# 这里捕获了HTTPError的异常,输出了reason、code和headers属性。
# 有时、reason属性返回的不一定是字符串,也可能是一个对象。

4、解析链接-parse模块

        urllib库里还提供parse模块,此模块定义了处理URL的标准接口,例如实现URL各部分的抽取合并以及链接转换

4.1、urlparse*

        该方法可以实现URL的识别和分段

from urllib.parse import urlparse
result = urlparse('htps://www.baidu.com/index.html;user?id=5#comment')
print(type(result))
print(result)# <class 'urllib.parse.ParseResult'>
# ParseResult(scheme='htps', netloc='www.baidu.com', path='/index.html;user', params='', query='id=5', fragment='comment')
# 解析结果是一个ParseResult类型的对象,包含六部分:scheme、netloc、path、params、query和fragment。

         urlparse的API用法:

urllib.parse.urlparse(urlstring,scheme='',allow_fragment=True)
  • urlstring:待解析的URL。
  • scheme:默认的协议(例如http或https)。
  • allow_fragment:是否忽略fragment。

4.2、urlunparse*

         对立方法urlunparse,用于构造URL。接收的参数是一个可迭代对象,其长度必须是6,否则抛出参数数量不足或过多的问题。

from urllib.parse import urlunparsedata = ['https','www.baidu.com','index.html','user','a=6','comment'] #列表类型,也可其它
print(urlunparse(data))  # https://www.baidu.com/index.html;user?a=6#comment 
# 成功构造URL

4.3、urlsplit*

        此方法和urlparse方法相似,不再单独解析params这一部分(params会合并到path中),返回5个结果。

from urllib.parse import urlsplitresult = urlsplit('https://www.baidu.com/index.html;user?id=5#comment')
print(result)    # SplitResult(scheme='https', netloc='www.baidu.com', path='/index.html;user', query='id=5', fragment='comment')# 也是一个元组,可以用属性名和索引获取
print(result.scheme,result[0])  # https https

4.5、urlunsplit*

        将链接各部分组成完整链接。传入的参数为可迭代对象,例如列表、元组,参数长度为5

from urllib.parse import urlunsplitdata = ['https','www.baidu.com','index.html','a=6','comment']
print(urlunsplit(data))  # https://www.baidu.com/index.html?a=6#comment

4.6、urljoin

        生成链接方法。先提供一个base_url(基础链接)作为第一个参数,将新的链接作为第二个参数。urljoin会解析base_url的scheme、netloc和path这三个内容。

from urllib.parse import urljoinprint(urljoin('https://www.baidu.com','FAQ.html'))
print(urljoin('https://www.baidu.com','https://cuiqingcai.com/FAQ.html'))
print(urljoin('https://www.baidu.com/about.html','https://cuiqingcai.com/FAQ.html'))
print(urljoin('https://www.baidu.com/about.html','https://cuiqingcai.com/FAQ.html?question=2'))
print(urljoin('https://www.baidu.com','https://cuiqingcai.com/FAQ.html/index.php'))
print(urljoin('https://www.baidu.com','?category=2#comment'))
print(urljoin('www.baidu.com','?category=2#comment'))
print(urljoin('www.baidu.com?#comment','?category=2'))#若干新链接不存在base_url中的三项,就予以补充;如果存在就用新链接里的,base_url是不起作用的。 

4.7、urlencode

        urlencode构造GET请求参数

from urllib.parse import urlencodeparams = {'name':'germey','age':25
}
base_url = 'https://www.baidu.com?'
url = base_url + urlencode(params)
print(url)   # https://www.baidu.com?name=germey&age=25 成功将字段类型转化为GET请求参数

4.8、parse_qs

 反序列化。可以将一串GET请求参数转回字典

from urllib.parse import parse_qsquery = 'name=germy&age=25'
print(parse_qs(query))#{'name': ['germy'], 'age': ['25']}

4.9、parse_qsl

        将参数转化为由元组组成的列表

from urllib.parse import parse_qslquery = 'name=germy&age=25'
print(parse_qsl(query))# [('name', 'germy'), ('age', '25')]

4.10、quote

        将内容转化为URL编码格式。当URL中带有中文参数时,有可能导致乱码问题,此时用quote方法可以将中文字符转为URL编码。

from urllib.parse import quotekeyword = '壁纸'
url = 'https://www.baidu.com/?wd=' + quote(keyword)
print(url)# https://www.baidu.com/?wd=%E5%A3%81%E7%BA%B8

4.11、unquote

        进行URL解码

url = https://www.baidu.com/?wd=%E5%A3%81%E7%BA%B8
print(unquote(url))
# https://www.baidu.com/?wd=壁纸

5、分析Robots协议

5.1、Robots协议

        Robots协议也称作爬虫协议、机器人协议,全名为网**络爬虫排除标准**,用来告诉爬虫和搜索引擎哪些页面可以抓取,哪些不可以!通常叫做robots.txt文件,在网站根目录下。

        搜索爬虫在访问一个网站时,先检查这个站点根目录下是否存在robots.txt文件,若存在,则根据其中定义的爬取范围来爬取。若无,则访问能访问到的页面。

# robots.txt文件样例:
# 限定搜索爬虫只能爬取public目录:
User-agent:*	# 搜索爬虫名称,*代表此文件对所有爬虫有效
Disallow:/		# 不允许爬虫爬取的目录,/代表不允许爬取所有页面
Allow:/public/	# 允许爬取的页面,和Disallow一起使用,用来排除限制。此表示可爬取public目录# 禁止所有爬虫访问所有目录:
User-agent:*
Disallow:/# 允许所有爬虫访问所有目录: robots.txt文件留空也是可以的
User-agent:*
Disallow:# 禁止所有爬虫访问网站某些目录:
User-agent:*
Disallow:/private/
Disallow:/tmp/# 只允许某一个爬虫访问所有目录:
User-agent:WebCrawler
Disallw:
User-agent:*
Disallw:/

5.2、爬虫名称

        其实,爬虫有固定名字。例如:

爬虫名称网站名称
BaiduSpider百度
Googlebot谷歌
360Spider369搜索
YodaoBot有道
ia_archiverAlexa
Scooteraltavista
Bingbot必应

5.3、rebotparser模块

        rebotparser模块解析robots.txt文件。该模块提供一个类RobotFileParser,它可以根据网站的robots.txt文件判断是否有权限爬取。  

# 用法:在构造方法里串robots.txt文件链接即可
urllib.rebotparser.RobotFileParser(url='')

        下面列出RobotFileParser类的几个常用方法:

  • set_url:设置tobots.txt的文件链接
  • read:读取robots.txt文件进行分析。记得调用,否则接下来的判断都为False
  • parse:解析tobots.txt文件
  • can_fetch:有两个参数,第一个是User-agent,第二个是要抓取的URL。返回结果True或False。表示User-agent指示的搜索引擎是否可以抓取这个URL
  • mtime:返回上次抓取和分析robots.txt文件的时间,这对长时间分析和抓取robots.txt文件的搜索爬虫很有必要。
  • modified:对于长时间分析和抓取的搜索爬虫重要,可以将当前时间设置为上次抓取和分析robots.txt文件的时间。
from urllib.robotparser import RobotFileParserrp = RobotFileParser()
rp.set_url('https://www.baidu.com/robots.txt')
rp.read()
print(rp.can_fetch('Baiduspider','https://www.baidu.com'))				# True
print(rp.can_fetch('Baiduspider','https://www.baidu.com/homepage/')) 	# True
print(rp.can_fetch('Googlebot','https://www.baidu.com/homepage/')) 		# False

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

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

相关文章

Chapter 2. A simple interconnection network

A Simple Interconnection Network 一个简单的互连网络 2.1 网络规范和约束2.2 拓扑2.3 路由2.4 流量控制2.5 路由器设计性能分析 A Simple Interconnection Network 一个简单的互连网络 我们将研究简单互连网络的架构和设计&#xff0c;以提供全局视图。我们将研究最简单的…

【数据结构初阶】之堆(C语言实现)

数据结构初阶之堆&#xff08;C语言实现&#xff09; &#x1f30f; 堆的概念&#x1f30f; 堆的模拟实现&#x1f413; 堆的结构和方法接口&#x1f413; 堆的方法的模拟实现&#x1f64a; 堆的初始化&#x1f64a; 堆的构建&#x1f64a; 堆的插入&#x1f64a; 向上调整&…

Postgresql中常见的执行计划解释

PostgreSQL中的执行计划&#xff08;或查询计划&#xff09;是数据库管理系统用来详细说明如何执行特定SQL查询的一系列操作步骤。简单来说&#xff0c;执行计划就是数据库如何解读你的SQL语句&#xff0c;并决定最有效率的方式去检索或更新所需数据的蓝图。 执行计划对于性能优…

【SysBench】OLTP 基准测试示例

前言 本文采用 MySQL 沙盒实例作为测试目标&#xff0c;使用 sysbench-1.20 对其做 OLTP 基准测试。 有关 MySQL 沙盒的更多信息&#xff0c;请参阅 玩转 MySQL Shell 沙盒实例&#xff0c;【MySQL Shell】6.8 AdminAPI MySQL 沙盒 。 1、部署一个 MySQL 沙盒实例 使用 mysq…

指尖论文怎么用 #经验分享#学习方法

指尖论文是一款优秀的论文写作、查重降重工具&#xff0c;被广泛认可为高效、可靠、方便的辅助工具。那么&#xff0c;如何正确地使用指尖论文呢&#xff1f; 首先&#xff0c;用户需要注册一个指尖论文的账号&#xff0c;并登录到平台上。注册过程非常简单&#xff0c;只需要输…

瑞芯微RK3576|触觉智能:开启科技新篇章

更多产品详情可关注深圳触觉智能官网&#xff01; “瑞芯微&#xff0c;创新不止步&#xff01;”——全新芯片RK3576即将震撼登场。指引科技风潮&#xff0c;创造未来无限可能&#xff01;这款芯片在瑞芯微不断创新和突破的道路上&#xff0c;不仅是对过往成就的完美延续&…

V R元宇宙平台的未来方向|V R主题馆加 盟|游戏体验馆

未来&#xff0c;VR元宇宙平台可能会呈现出以下发展趋势和可能性&#xff1a; 全面融合现实与虚拟世界&#xff1a; VR元宇宙平台将更加无缝地融合现实世界和虚拟世界&#xff0c;用户可以在虚拟环境中进行各种活动&#xff0c;与现实世界进行互动&#xff0c;并且体验到更加逼…

Golang基础 Label标签与goto跳转

使用方法 Label 和goto是必须的 Label可以声明再函数体的任何地方 Label的作用范围是在函数体中 Label在嵌套函数(闭包)是不可用的. 不管是在闭包里调用闭包外的Label, 还是在闭包外调用闭包里的Label 变量的声明必须在goto之前 示例 package mainimport "fmt"…

数据仓库建模方法万字详解

在数据仓库的建设过程中&#xff0c;数据建模是至关重要的一环。它决定了数据仓库的结构和性能&#xff0c;直接影响到数据分析和决策的效率和准确性。在进行数据建模之前&#xff0c;必须对企业进行全面的业务梳理。通过建立业务模型&#xff0c;我们可以全面了解企业的业务架…

FileZilla 链接服务器提示 20 秒连接超时

FileZilla 有个默认设置是如果 20 秒没有数据的话会自动中断链接。 Command: Pass: **************** Error: Connection timed out after 20 seconds of inactivity Error: Could not connect to server修改配置 这个配置是可以修改的&#xff0c;修改的步骤为&#xff1a; …

数据可视化-ECharts Html项目实战(5)

在之前的文章中&#xff0c;我们学习了如何设置滚动图例&#xff0c;工具箱设置和插入图片。想了解的朋友可以查看这篇文章。同时&#xff0c;希望我的文章能帮助到你&#xff0c;如果觉得我的文章写的不错&#xff0c;请留下你宝贵的点赞&#xff0c;谢谢 数据可视化-ECharts…

Vue3 + Django 前后端分离项目实现密码认证登录

1、功能需求 通常中小型前后端项目&#xff0c;对安全要求不高&#xff0c;也可以采用密码认证方案。如果只用django来实现非常简单。采用 Vue3 前后端分离架构&#xff0c;实现起来稍繁琐一点&#xff0c;好处是可以利用各种前端技术栈&#xff0c;如element-plus UI库来渲染…

[C#] .NET8增加了Arm架构的多寄存器的查表函数(VectorTableLookup/VectorTableLookupExtension)

发现.NET8增加了Arm架构的多寄存器的查表函数&#xff08;VectorTableLookup/VectorTableLookupExtension&#xff09;&#xff0c;这给编写SIMD向量化算法带来了方便。 一、指令说明 在学习Arm的AdvSimd&#xff08;Neon&#xff09;指令集时&#xff0c;发现它的Lookup&…

Git Commit 提交规范,变更日志、版本发布自动化和 Emoji 提交标准

前言 Git Commit 是开发的日常操作, 一个优秀的 Commit Message 不仅有助于他人 Review, 还可以有效的输出 CHANGELOG, 对项目的管理实际至关重要, 但是实际工作中却常常被大家忽略&#xff0c;希望通过本文&#xff0c;能够帮助大家规范 Git Commit&#xff0c;并且展示相关 …

Spring Cloud微服务功能及其组件详细讲解

Spring Cloud微服务功能及其组件详细讲解 文章目录 Spring Cloud微服务功能及其组件详细讲解前言&#xff1a;什么是微服务&#xff1f;一、Spring Cloud原理简述二、核心组件1、服务发现——Nacos/Eureka/Consul1&#xff09;Nacos服务发现2&#xff09;Eureka服务发现3&#…

优化 - 排序算法

一、概念 冒泡排序从左往右比较相邻的两个元素&#xff0c;右比左小就换位&#xff0c;这样最大值就出现在了右边最后一个元素上&#xff0c;再从左边第一个元素开始往右比较到倒数第二个元素&#xff0c;如此重复...选择排序 通过线性查找&#xff08;从左往右挨个查找&#…

Mongodb入门到入土,安装到实战,外包半年学习的成果

这是我参与「第四届青训营 」笔记创作活动的的第27天&#xff0c;今天主要记录前端进阶必须掌握内容Mongodb数据库,从搭建环境到运行数据库,然后使用MongodB; 一、文章内容 数据库基础知识关系型数据库和非关系型数据库为什么学习Mongodb数据库环境搭建及运行MongodbMongodb命…

【进程概念】启动进程 | 查看进程 | 创建进程

目录 启动进程 查看进程 方法1&#xff1a;/proc 方法2&#xff1a;查看脚本 ​方法3&#xff1a;系统调用获取进程标示符❗❗ 终止进程 创建进程&#xff08;主fork) &#x1f642;查看父子进程的pid &#x1f642;进程创建/执行/终止 &#x1f642;多次重新启动进…

Pycharm运行yolov5报错Error: Failed to initialize: Bad git executable.错误的解决方案

一、报错代码 ImportError: Failed to initialize: Bad git executable. The git executable must be specified in one of the following ways:- be included in your $PATH- be set via $GIT_PYTHON_GIT_EXECUTABLE- explicitly set via git.refresh()All git commands will…

STM32 CAN的工作模式

STM32 CAN的工作模式 正常模式 正常模式下就是一个正常的CAN节点&#xff0c;可以向总线发送数据和接收数据。 静默模式 静默模式下&#xff0c;它自己的输出端的逻辑0数据会直接传输到它自己的输入端&#xff0c;逻辑1可以被发送到总线&#xff0c;所以它不能向总线发送显性…