百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 编程字典 > 正文

Python中urllib库详解

toyiye 2024-06-21 12:40 11 浏览 0 评论

博主强烈推荐:

Java17中文文档:Overview - Java17中文文档 - API参考文档 - 全栈行动派

Linux命令在线查询工具:Linux命令查询 - 全栈工具箱 - 在线工具箱 - 免费实用工具大全

Gradle最新中文文档:Gradle用户手册 - Gradle8.1.1中文文档 - API参考文档 - 全栈行动派Gradlegithubgradle

更多好文章参见博主自己的博客系统:全栈行动派-全栈技术博客

1、概述

Python urllib 库用于操作网页 URL,并对网页的内容进行抓取处理。

主要包含模块有:

模块

描述

urllib.request

模拟浏览器从服务器获取内容。

urllib.error

包含 urllib.request 抛出的异常。

urllib.parse

解析、编码URL

urllib.robotparser

解析 robots.txt 文件。

2、urllib.request

urllib.request 定义了一些打开 URL 的函数和类,包含授权验证、重定向、浏览器 cookies等。

urllib.request 可以模拟浏览器的一个请求发起过程。

实例①:获取百度首页源码(填坑)

import urllib.request

# 定义URL
url = "http://www.baidu.com/"

# 模拟浏览器向服务器发起请求获取响应
response = urllib.request.urlopen(url)

# 获取响应内容
content = response.read()

# 打印内容
print(content)

注意:如果发现获取的内容开头是"b"字母,读取的是字节,需要转换为相应的编码格式,具体转换成什么编码格式,则需要看要获取的网页源码的Content-Type元素值。

改造代码,增加字节编码解析

# 获取响应内容
content = response.read().decode('utf-8')

2.1、response方法列表

方法

描述

read()

字节形式读取二进制

read(num)

字节形式读取二进制,读取前几个字节

readline()

读取一行数据

readlines()

一行一行读取,直到结束

getcode()

获取响应状态码

geturl()

获取请求的URL

getheaders()

获取请求头

注意:读取数据时,如果已经读取再次调用方法是不会返回数据的

2.2、请求增加header

我们将请求百度首页的URL地址由http换为https,在不增加请求头的情况下,会遇到反爬,返回内容如下:

这个时候我们就需要在headers中增加UA

获取百度首页URL的UA(其他网页地址获取UA方式一致)

改造代码:

import urllib.request

# 定义URL
url = "https://www.baidu.com/"

# headers
headers = {
    "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36"
}

# 构建request
request = urllib.request.Request(url=url, headers=headers)

# 模拟浏览器向服务器发起请求获取响应
response = urllib.request.urlopen(request)

# 第一次获取全部内容
content = response.read().decode('utf-8')

# 打印内容
print(content)

2.3、get请求增加参数

先看下百度首页搜索的请求

改造代码:

import urllib.request

# 定义URL
url = "https://www.baidu.com/s?wd="

# headers
headers = {
    "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36"
}

url += "java"

# 构建request
request = urllib.request.Request(url=url, headers=headers)

# 模拟浏览器向服务器发起请求获取响应
response = urllib.request.urlopen(request)

# 第一次获取全部内容
content = response.read().decode('utf-8')

# 打印内容
print(content)

因为上面查询的关键字”java“是字母,换成中文则会报错

因为请求URL只识别ascii码,这个时候就需要用到urllib.parse 模块了

3、urllib.parse

我们将2.3代码改造下

# 导入包
import urllib.request
import urllib.parse

# 定义URL
url = "https://www.baidu.com/s?wd="

# headers
headers = {
    "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36"
}
# 将中文编码为ascii码
url += urllib.parse.quote("中文")

# 构建request
request = urllib.request.Request(url=url, headers=headers)

# 模拟浏览器向服务器发起请求获取响应
response = urllib.request.urlopen(request)

# 第一次获取全部内容
content = response.read().decode('utf-8')

# 打印内容
print(content)

这种方式只能一个一个参数处理,多个参数处理方式

data = {
    "kw": "中文",
    "other": "也是中文"
}
# 打印结果:kw=%E4%B8%AD%E6%96%87&other=%E4%B9%9F%E6%98%AF%E4%B8%AD%E6%96%87
print(urllib.parse.urlencode(data))

多参数改造:

import urllib.request
import urllib.parse

# 定义URL
url = "https://www.baidu.com/s"

# headers
headers = {
    "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36"
}
# 定义多参数
data = {
    "kw": "中文",
    "other": "也是中文"
}
# 将参数编码,附加在URL后面
url += "?" + urllib.parse.urlencode(data)

# 构建request
request = urllib.request.Request(url=url, headers=headers)

# 模拟浏览器向服务器发起请求获取响应
response = urllib.request.urlopen(request)

# 第一次获取全部内容
content = response.read().decode('utf-8')

# 打印内容
print(content)

4、urllib.error

我们将3的代码改造,将地址写错增加错误捕获

import urllib.request
import urllib.parse
import urllib.error

# 定义URL
url = "https://www.baidu.com3/s"

# headers
headers = {
    "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36"
}

data = {
    "kw": "中文",
    "other": "也是中文"
}

url += "?" + urllib.parse.urlencode(data)

# 构建request
request = urllib.request.Request(url=url, headers=headers)

# 模拟浏览器向服务器发起请求获取响应
try:
    response = urllib.request.urlopen(request)

    print(f"本次请求响应状态码:{response.getcode()}")

    # 第一次获取全部内容
    content = response.read().decode('utf-8')

    # 打印内容
    print(content)
except urllib.error.HTTPError as e:
    if e.code == 404:
        print("地址未找到")
    else:
        print("其他错误")
except urllib.error.URLError as e:
    print(f"URLError:{e.reason}")

5、post请求

post请求是不能通过url传参,就得换另一种方式,咱们以百度翻译为例

改造代码,增加post请求入参

import urllib.request
import urllib.parse

url = "https://fanyi.baidu.com/sug"

headers = {
    "User-Agent": 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36'
}

data = {
    "kw": "python"
}

# 编码请求参数,注意这里还得再次encode
data = urllib.parse.urlencode(data).encode("utf-8")

# 构建request
request = urllib.request.Request(url=url, data=data, headers=headers)

# 构建response
response = urllib.request.urlopen(request)

# 获取响应
content = response.read().decode('utf-8')

print(content)

但是响应结果:

说明我们的请求不符合要求,的改造请求头

这里注意:一定不能将“Accept-Encoding” 加入请求头,否则获取的数据解码失败,报错信息如下:

UnicodeDecodeError: 'utf-8' codec can't decode byte 0x8b in position 1:invalid start byte

改造后代码:

import urllib.request
import urllib.parse
import json

url = "https://fanyi.baidu.com/sug"

headers = {
    'Accept': 'application/json, text/javascript, */*; q=0.01',
    'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8',
    'Connection': 'keep-alive',
    'Content-Length': '9',
    'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
    'Cookie': 'xxxxx',
    'Host': 'fanyi.baidu.com',
    'Origin': 'https://fanyi.baidu.com',
    'Referer': 'https://fanyi.baidu.com/',
    'sec-ch-ua': '"Google Chrome";v="111", "Not(A:Brand";v="8", "Chromium";v="111"',
    'sec-ch-ua-mobile': '?0',
    'sec-ch-ua-platform': '"macOS"',
    'Sec-Fetch-Dest': 'empty',
    'Sec-Fetch-Mode': 'cors',
    'Sec-Fetch-Site': 'same-origin',
    'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36',
    'X-Requested-With': 'XMLHttpRequest',
}

data = {
    "kw": "python"
}

# 编码请求参数,注意这里还得再次encode
data = urllib.parse.urlencode(data).encode("utf-8")

# 构建request
request = urllib.request.Request(url=url, data=data, headers=headers)

# 构建response
response = urllib.request.urlopen(request)

# 获取响应
content = response.read().decode("utf-8")

# 因为获取到的数据是JSON格式,需要将字符串转换为JSON格式
obj = json.loads(content)

print(obj)

响应结果:

6、网页、图片、视频下载

代码:

import urllib.request
# 要下载的URL
url = "http://www.baidu.com/"

# 请求下载,filename为要存储为文件名称
urllib.request.urlretrieve(url=url, filename="baidu.html")

相关推荐

为何越来越多的编程语言使用JSON(为什么编程)

JSON是JavascriptObjectNotation的缩写,意思是Javascript对象表示法,是一种易于人类阅读和对编程友好的文本数据传递方法,是JavaScript语言规范定义的一个子...

何时在数据库中使用 JSON(数据库用json格式存储)

在本文中,您将了解何时应考虑将JSON数据类型添加到表中以及何时应避免使用它们。每天?分享?最新?软件?开发?,Devops,敏捷?,测试?以及?项目?管理?最新?,最热门?的?文章?,每天?花?...

MySQL 从零开始:05 数据类型(mysql数据类型有哪些,并举例)

前面的讲解中已经接触到了表的创建,表的创建是对字段的声明,比如:上述语句声明了字段的名称、类型、所占空间、默认值和是否可以为空等信息。其中的int、varchar、char和decimal都...

JSON对象花样进阶(json格式对象)

一、引言在现代Web开发中,JSON(JavaScriptObjectNotation)已经成为数据交换的标准格式。无论是从前端向后端发送数据,还是从后端接收数据,JSON都是不可或缺的一部分。...

深入理解 JSON 和 Form-data(json和formdata提交区别)

在讨论现代网络开发与API设计的语境下,理解客户端和服务器间如何有效且可靠地交换数据变得尤为关键。这里,特别值得关注的是两种主流数据格式:...

JSON 语法(json 语法 priority)

JSON语法是JavaScript语法的子集。JSON语法规则JSON语法是JavaScript对象表示法语法的子集。数据在名称/值对中数据由逗号分隔花括号保存对象方括号保存数组JS...

JSON语法详解(json的语法规则)

JSON语法规则JSON语法是JavaScript对象表示法语法的子集。数据在名称/值对中数据由逗号分隔大括号保存对象中括号保存数组注意:json的key是字符串,且必须是双引号,不能是单引号...

MySQL JSON数据类型操作(mysql的json)

概述mysql自5.7.8版本开始,就支持了json结构的数据存储和查询,这表明了mysql也在不断的学习和增加nosql数据库的有点。但mysql毕竟是关系型数据库,在处理json这种非结构化的数据...

JSON的数据模式(json数据格式示例)

像XML模式一样,JSON数据格式也有Schema,这是一个基于JSON格式的规范。JSON模式也以JSON格式编写。它用于验证JSON数据。JSON模式示例以下代码显示了基本的JSON模式。{"...

前端学习——JSON格式详解(后端json格式)

JSON(JavaScriptObjectNotation)是一种轻量级的数据交换格式。易于人阅读和编写。同时也易于机器解析和生成。它基于JavaScriptProgrammingLa...

什么是 JSON:详解 JSON 及其优势(什么叫json)

现在程序员还有谁不知道JSON吗?无论对于前端还是后端,JSON都是一种常见的数据格式。那么JSON到底是什么呢?JSON的定义...

PostgreSQL JSON 类型:处理结构化数据

PostgreSQL提供JSON类型,以存储结构化数据。JSON是一种开放的数据格式,可用于存储各种类型的值。什么是JSON类型?JSON类型表示JSON(JavaScriptO...

JavaScript:JSON、三种包装类(javascript 包)

JOSN:我们希望可以将一个对象在不同的语言中进行传递,以达到通信的目的,最佳方式就是将一个对象转换为字符串的形式JSON(JavaScriptObjectNotation)-JS的对象表示法...

Python数据分析 只要1分钟 教你玩转JSON 全程干货

Json简介:Json,全名JavaScriptObjectNotation,JSON(JavaScriptObjectNotation(记号、标记))是一种轻量级的数据交换格式。它基于J...

比较一下JSON与XML两种数据格式?(json和xml哪个好)

JSON(JavaScriptObjectNotation)和XML(eXtensibleMarkupLanguage)是在日常开发中比较常用的两种数据格式,它们主要的作用就是用来进行数据的传...

取消回复欢迎 发表评论:

请填写验证码