当前位置: 首页 > news >正文

Python爬虫之urllib库使用总结

urllib 是 Python 内置的一个用于操作 URL 的库。它提供了用于打开和读取 URL 的功能,可以处理 HTTP、HTTPS 等多种协议。urllib 包含几个子模块,每个都有不同的用途:

  • urllib.request: 用于打开和读取 URLs。
  • urllib.error: 包含 urllib.request 抛出的异常。
  • urllib.parse: 用于解析 URLs。
  • urllib.robotparser: 用于解析 robots.txt 文件。

请注意,虽然 urllib 库是 Python 标准库的一部分,并且适用于简单的任务,但对于更复杂的 Web 爬虫项目,通常会推荐使用像 requests 这样的第三方库,因为它们提供了更简洁的 API 和更好的特性支持,如会话管理、SSL 验证、Cookies 等等。

【1】基础入门

响应数据解码decode

# 使用urllib来获取百度首页的源码
import urllib.request# (1)定义一个url  就是你要访问的地址
url = 'http://www.baidu.com'# (2)模拟浏览器向服务器发送请求 response响应
response = urllib.request.urlopen(url)# (3)获取响应中的页面的源码  content 内容的意思
# read方法  返回的是字节形式的二进制数据
# 我们要将二进制的数据转换为字符串
# 二进制--》字符串  解码  decode('编码的格式')
content = response.read().decode('utf-8')# (4)打印数据
print(content)

发送 GET 请求

import urllib.request# 发送一个简单的GET请求
response = urllib.request.urlopen('http://www.example.com')
html = response.read()# 打印返回的内容
print(html)

发送 POST 请求

import urllib.parse
import urllib.requesturl = 'http://www.example.com/login'
values = {'username': 'myusername','password': 'mypassword'}data = urllib.parse.urlencode(values).encode('utf-8') # 转换为bytes类型
req = urllib.request.Request(url, data)
with urllib.request.urlopen(req) as response:the_page = response.read()print(the_page)

如何判断GET还是POST请求?

urllib.request.urlopen 本身并不直接提供方法来判断请求是 GET 还是 POST。这是因为 urllib.request.urlopen 主要用于打开和读取 URL,而具体的 HTTP 方法(GET 或 POST)是由你传递给它的参数决定的。

urllib.request.urlopen 中,HTTP 请求的方法取决于你如何构造 Request 对象:

  • 如果你只提供了一个 URL 给 urllib.request.urlopen,它会默认发送一个 GET 请求。
  • 如果你提供了一个 Request 对象,并且这个对象有一个非空的数据字段(即 data 参数),那么 urllib.request.urlopen 会发送一个 POST 请求。

处理异常

在进行网络请求时,可能会遇到各种问题,比如网络连接失败或服务器端错误。你可以使用 urllib.error 来捕获这些异常:

from urllib.request import urlopen
from urllib.error import URLError, HTTPErrortry:response = urlopen('http://www.nonexistentwebsite.com')
except HTTPError as e:print('The server couldn\'t fulfill the request.')print('Error code: ', e.code)
except URLError as e:print('We failed to reach a server.')print('Reason: ', e.reason)
else:# everything is finehtml = response.read()print(html)

解析 URL

如果你需要从 URL 中提取信息,可以使用 urllib.parse 模块:

from urllib.parse import urlparseresult = urlparse('http://www.example.com/path/to/page?name=ferret&color=purple')
print(result.scheme, result.netloc, result.path, result.params, result.query, result.fragment)

【2】一个类型和六个方法

一个类型:HTTPResponse
六个方法 :read readline readlines getcode geturl getheaders

import urllib.requesturl = 'http://www.baidu.com'# 模拟浏览器向服务器发送请求
response = urllib.request.urlopen(url)# 一个类型和六个方法
# response是HTTPResponse的类型
# print(type(response))# 按照一个字节一个字节的去读
# content = response.read()
# print(content)# 返回多少个字节
# content = response.read(5)
# print(content)# 读取一行
# content = response.readline()
# print(content)# content = response.readlines()
# print(content)# 返回状态码  如果是200了 那么就证明我们的逻辑没有错
# print(response.getcode())# 返回的是url地址
# print(response.geturl())# 获取是一个状态信息
print(response.getheaders())# 一个类型 HTTPResponse
# 六个方法 read  readline  readlines  getcode geturl getheaders

【3】文件下载

import urllib.request# 下载网页
# url_page = 'http://www.baidu.com'# url代表的是下载的路径  filename文件的名字
# 在python中 可以变量的名字  也可以直接写值
# urllib.request.urlretrieve(url_page,'baidu.html')# 下载图片
# url_img = 'https://img1.baidu.com/it/u=3004965690,4089234593&fm=26&fmt=auto&gp=0.jpg'
#
# urllib.request.urlretrieve(url= url_img,filename='lisa.jpg')# 下载视频
url_video = 'https://vd3.bdstatic.com/mda-mhkku4ndaka5etk3/1080p/cae_h264/1629557146541497769/mda-mhkku4ndaka5etk3.mp4?v_from_s=hkapp-haokan-tucheng&auth_key=1629687514-0-0-7ed57ed7d1168bb1f06d18a4ea214300&bcevod_channel=searchbox_feed&pd=1&pt=3&abtest='urllib.request.urlretrieve(url_video,'hxekyyds.mp4')

【4】请求对象的定制

import urllib.requesturl = 'https://www.baidu.com'# url的组成
# https://www.baidu.com/s?wd=周杰伦# http/https    www.baidu.com   80/443     s      wd = 周杰伦     #
#    协议             主机        端口号     路径     参数           锚点
# http   80
# https  443
# mysql  3306
# oracle 1521
# redis  6379
# mongodb 27017headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36'
}# 因为urlopen方法中不能存储字典 所以headers不能传递进去
# 请求对象的定制
request = urllib.request.Request(url=url,headers=headers)// GET请求
response = urllib.request.urlopen(request)content = response.read().decode('utf8')print(content)// 或者如下
with urllib.request.urlopen(req) as response:html = response.read()
print(html)

【5】GET请求的编码解码

① quote方法对中文进行编码

# https://www.baidu.com/s?wd=%E5%91%A8%E6%9D%B0%E4%BC%A6
# 需求 获取 https://www.baidu.com/s?wd=周杰伦的网页源码import urllib.request
import urllib.parseurl = 'https://www.baidu.com/s?wd='# 请求对象的定制为了解决反爬的第一种手段
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36'
}# 将周杰伦三个字变成unicode编码的格式
# 我们需要依赖于urllib.parse
name = urllib.parse.quote('周杰伦')url = url + name# 请求对象的定制
request = urllib.request.Request(url=url,headers=headers)# 模拟浏览器向服务器发送请求
response = urllib.request.urlopen(request)# 获取响应的内容
content = response.read().decode('utf-8')# 打印数据
print(content)

② urlencode对参数进行编码

urlencode应用场景:多个参数的时候

# https://www.baidu.com/s?wd=周杰伦&sex=男# import urllib.parse
#
# data = {
#     'wd':'周杰伦',
#     'sex':'男',
#     'location':'中国台湾省'
# }
#
# a = urllib.parse.urlencode(data)
# print(a)#获取https://www.baidu.com/s?wd=%E5%91%A8%E6%9D%B0%E4%BC%A6&sex=%E7%94%B7的网页源码import urllib.request
import urllib.parsebase_url = 'https://www.baidu.com/s?'data = {'wd':'周杰伦','sex':'男','location':'中国台湾省'
}new_data = urllib.parse.urlencode(data)# 请求资源路径
url = base_url + new_dataheaders = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36'
}# 请求对象的定制
request = urllib.request.Request(url=url,headers=headers)# 模拟浏览器向服务器发送请求
response = urllib.request.urlopen(request)# 获取网页源码的数据
content = response.read().decode('utf-8')# 打印数据
print(content)

【6】POST请求

  • post请求方式的参数 必须编码 data = urllib.parse.urlencode(data)
  • 编码之后 必须调用encode方法
    • data = urllib.parse.urlencode(data).encode('utf-8')
  • 参数是放在请求对象定制的方法中
    • request = urllib.request.Request(url=url,data=data,headers=headers)
# post请求import urllib.request
import urllib.parseurl = 'https://fanyi.baidu.com/sug'headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36'
}data = {'kw':'spider'
}# post请求的参数 必须要进行编码
data = urllib.parse.urlencode(data).encode('utf-8')# post的请求的参数 是不会拼接在url的后面的  而是需要放在请求对象定制的参数中
# post请求的参数 必须要进行编码
request = urllib.request.Request(url=url,data=data,headers=headers)# 模拟浏览器向服务器发送请求
response = urllib.request.urlopen(request)# 获取响应的数据
content = response.read().decode('utf-8')# 字符串--》json对象import jsonobj = json.loads(content)
print(obj)

【7】Handler处理器的使用

为什么要学习handler?

  • 不能定制请求头
urllib.request.urlopen(url)
  • 可以定制请求头
urllib.request.Request(url,headers,data)
  • Handler定制更高级的请求头

定制更高级的请求头(随着业务逻辑的复杂 请求对象的定制已经满足不了我们的需求(动态cookie和代理不能使用请求对象的定制)

import urllib.requesturl = 'http://www.baidu.com'headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36'
}request = urllib.request.Request(url = url,headers = headers)# handler   build_opener  open# (1)获取hanlder对象
handler = urllib.request.HTTPHandler()# (2)获取opener对象
opener = urllib.request.build_opener(handler)# (3) 调用open方法
response = opener.open(request)content = response.read().decode('utf-8')print(content)

【8】代理的使用

1.代理的常用功能?

  • 1.突破自身IP访问限制,访问国外站点。

  • 2.访问一些单位或团体内部资源

    扩展:某大学FTP(前提是该代理地址在该资源的允许访问范围之内),使用教育网内地址段免费代理服务器,就可以用于对教育网开放的各类FTP下载上传,以及各类资料查询共享等服务。

  • 3.提高访问速度

    扩展:通常代理服务器都设置一个较大的硬盘缓冲区,当有外界的信息通过时,同时也将其保存到缓冲区中,当其他用户再访问相同的信息时, 则直接由缓冲区中取出信息,传给用户,以提高访问速度。

  • 4.隐藏真实IP

    扩展:上网者也可以通过这种方法隐藏自己的IP,免受攻击。

2.代码配置代理

  • 创建Reuqest对象
  • 创建ProxyHandler对象
  • 用handler对象创建opener对象
  • 使用opener.open函数发送请求

使用单个固定代理

import urllib.requesturl = 'http://www.baidu.com/s?wd=ip'headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36'
}# 请求对象的定制
request = urllib.request.Request(url = url,headers= headers)# 模拟浏览器访问服务器
# response = urllib.request.urlopen(request)proxies = {'http':'118.24.219.151:16817'
}
# handler  build_opener  open
handler = urllib.request.ProxyHandler(proxies = proxies)opener = urllib.request.build_opener(handler)response = opener.open(request)# 获取响应的信息
content = response.read().decode('utf-8')# 保存
with open('daili.html','w',encoding='utf-8')as fp:fp.write(content)

使用代理池

import urllib.requestproxies_pool = [{'http':'118.24.219.151:16817'},{'http':'118.24.219.151:16817'},
]import randomproxies = random.choice(proxies_pool)url = 'http://www.baidu.com/s?wd=ip'headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36'
}request = urllib.request.Request(url = url,headers=headers)handler = urllib.request.ProxyHandler(proxies=proxies)opener = urllib.request.build_opener(handler)response = opener.open(request)content = response.read().decode('utf-8')with open('daili.html','w',encoding='utf-8')as fp:fp.write(content)

可以从网上寻找一些免费代理,如果需要稳定可靠的可以尝试购买付费代理,比如快代理。


http://www.mrgr.cn/news/79724.html

相关文章:

  • Ubuntu中配置交叉编译工具的三条命令的详细研究
  • Maven插件打包发布远程Docker镜像
  • Docker在Ubuntu和CentOS系统下的安装
  • WebSocket解读
  • linux 注销时删除命令记录阻止任何人su作为root
  • IMX6ULL开发板、PC机上的USB网卡、VMware中的Ubuntu的桥接网卡三者互Ping设置及设置
  • Mac软件推荐
  • maxscript中BoundingBox求一个模型的高度
  • C#-WPF 常见类型转换方法(持续更新)
  • 5G Multi-TRP R16~R18演进历程
  • Linux网络基础知识————网络编程
  • rk3588-ubuntu22.04系统网关实现路由器功能:
  • 《Hadoop大数据技术应用综合训练》----以NBA冠军球队计数为例
  • C# .NET CORE 开发问题汇总
  • day10 电商系统后台API——接口测试(使用postman)
  • 【Spark】Spark Join类型及Join实现方式
  • 数据结构DAY1
  • 开发EDA工具常用的三方开源
  • 第七天:Linux中文本编辑工具和文本三剑客-grep 第八天:Linux中shell脚本编程1
  • python爬虫--小白篇【爬虫实践】
  • FPGA 17 ,FPGA 与 SR-IOV虚拟化技术,高性能计算与虚拟化技术的结合(FPGA 与 SR-IOV 和 PCI,高性能计算与虚拟化的完美融合)
  • python学opencv|读取图像(七)抓取像素数据顺利修改图像大小
  • Flutter:开发环境搭建和Android Studio创建Flutter Project
  • Harbor 仓库部署(docker-compose 部署方式)
  • coco数据集转换SAM2格式
  • 文件下载和图片预览 Blob FileReader