项目6 使用Python模块(课件)-《Python程序设计》同步教学(机工教育版)

2024-08-14
| 54页
| 58人阅读
| 8人下载
普通

内容正文:

项目6 使用Python模块 2023年12月 1 使用Urllib模块获取网页数据 目录 Content 1 使用re模块过滤数据 2 使用PyMySQL模块存储数 3 项目导言 零 网页数据采集是指从网页中获取所需的信息,通常情况下,使用Python编程语言来实现。Python提供了许多库和工具,如Urllib、Requests、re、PyMySQL等,可以发送HTTP 请求、解析HTML页面并在提取所需内容后将其保存。网页数据采集可以用于各种用途,例如市场调查、竞争分析、舆情监测等。但在进行网页数据采集时,需要注意反爬虫机制、请求频率限制、数据质量等问题。本项目主要通过Urllib、re、PyMySQL等Python模块的组合实现网页数据的采集与存储。 3 学习目标 零 知识目标 了解Python模块的作用; 熟悉正则表达式组成; 掌握Python中数据库的连接; 掌握正则表达式元字符含义。 能力目标 具备使用正则表达式匹配文本的能力; 具备Python模块下载安装的能力; 具备网页数据采集与存储的能力。 素养目标 具备精益求精、坚持不懈的精神; 具有良好的行为习惯和良好的心理素质; 具备灵活的思维和处理分析问题的能力; 具有发现问题、分析问题、解决问题的能力。 4 任务6-1:使用Urllib模块获取网页数据 壹 1 request模块 在Urllib中,request模块提供了许多与网络通信相关的功能,可以用来向 HTTP/HTTPS服务器发送请求并获取响应结果,以实现数据的获取或提交,并通过该模块中的函数和类来实现常见的HTTP操作 向指定URL发送请求,并获取响应结果 发送POST请求,并添加数据 添加请求头部信息 处理Cookies,以便在请求之间保持会话 处理重定向 指定代理 HTTP认证 5 任务6-1:使用Urllib模块获取网页数据 壹 request模块包含的常用函数见表。 函数 描述 urlopen() 用于向指定URL发送请求,并获取响应结果 Request() 构造一个HTTP请求 urlencode() 将字典、元组列表等对象转换为URL编码格式 urlretrieve() 用于以文件形式下载指定URL的内容 6 任务6-1:使用Urllib模块获取网页数据 壹 (1)urlopen() 在request模块中,urlopen()函数支持HTTP、HTTPS、FTP和文件等多种协议,并在指定请求方式、请求头等信息后打开指定的URL,语法格式如下所示。 urllib.request.urlopen(url, data=None, timeout=socket._GLOBAL_DEFAULT_TIMEOUT, cafile=None, capath=None, cadefault=False, context=None) 参数说明见表。 参数 描述 url 要访问的URL地址,可以是字符串类型的URL,也可以是一个Request对象 data 发送给服务器的数据。如果为None,则发送GET请求;否则,发送POST请求并把数据添加到请求体中 timeout 设置超时时间,单位为秒。如果访问时响应时间超过了这个设定的时间,则会抛出异常。默认值为全局超时,默认超时时间为socket._GLOBAL_DEFAULT_TIMEOUT cafile 用于指定SSL/TLS证书文件的路径,默认值为None capath 用于指定SSL/TLS证书文件夹的路径,默认值为None cadefault 指示是否使用默认的SSL/TLS验证机制,默认值为False context 指定ssl.SSLContext实例,用于为HTTPS请求配置SSL/TLS,默认值为None 7 任务6-1:使用Urllib模块获取网页数据 壹 例如,使用urlopen()函数访问地址“http://www.example.com/”,代码如下。 import urllib.request response = urllib.request.urlopen('http://www.example.com/') 需要注意的是,urlopen()函数在读取响应内容时会将整个响应内容加载到内存中,对于大文件或网络延迟较高的情况可能会导致程序崩溃或资源耗尽。因此,在处理大文件时,建议使用其他方式进行下载和处理,如使用requests库等。 8 任务6-1:使用Urllib模块获取网页数据 壹 另外,urlopen()函数在完成URL地址的访问后,会返回一个类文件对象(Response),其包含多项内容,如:  状态码:表示服务器返回的状态代码,是服务器返回的一个三位数字代码,用于表示HTTP请求的处理结果。HTTP响应状态码有5类,各代表不同的含义,见表。 类别 描述 1xx 信息性状态码,表示服务器已经接收到请求并正在处理 2xx 成功状态码,表示服务器已经成功地接收、理解和接受请求 3xx 重定向状态码,表示客户端需要执行额外的操作才能完成请求 4xx 客户端错误状态码,表示客户端请求有语法错误或者请求无法实现 5xx 服务器错误状态码,表示服务器在处理请求时发生了错误 9 任务6-1:使用Urllib模块获取网页数据 壹 常见的HTTP响应状态码及其含义见表。 参数 描述 200 OK 服务器成功返回请求的数据 201 Created 请求已经被实现,新的资源已经被创建 204 No Content 服务器成功处理了请求,但没有返回任何内容 301 Moved Permanently 请求的网页已被永久移动到新的位置 304 Not Modified 请求的资源未修改,服务器返回此响应时,不会返回资源的内容 400 Bad Request 请求语法错误 401 Unauthorized 请求需要用户验证 403 Forbidden 服务器拒绝请求 404 Not Found 请求的资源不存在 500 Internal Server Error 服务器内部错误 10 任务6-1:使用Urllib模块获取网页数据 壹 头部信息:表示服务器返回的HTTP头部信息。 响应内容:表示服务器返回的内容。 并且,对于Response对象,开发人员可以通过其提供的方法和属性获取服务器返回的各种信息,常用方法和属性见表。 方法和属性 描述 status_code/code 获取HTTP请求的响应状态码 headers 获取响应头信息,以字典形式返回 text 获取响应内容,以字符串形式返回 content 获取响应内容,以字节形式返回 url 获取HTTP响应的最终URL json() 将响应内容解析成JSON格式的数据,以Python对象形式返回 read([size]) 读取响应内容,并以字节形式返回。如果指定了size参数,则最多读取size个字节。 readline() 读取响应内容中的一行,并以字节形式返回 readlines() 读取所有数据,并将数据拆分成一个行列表 getcode() 获取状态码 geturl() 获取请求的URL地址 decode(encoding='utf-8', errors='strict') 将字节串转换为字符串,使用指定的编码方式进行解码,默认使用utf-8编码。该方法返回一个字符串类型数据 getheaders() 获取所有的响应头信息,返回一个列表,每个元素为(name, value)的二元组 info() 获取响应头信息,等同于调用getheaders()方法 getheader(name, default=None) 获取指定名称的响应头信息,如果不存在该头信息,则返回默认值 11 任务6-1:使用Urllib模块获取网页数据 壹 例如,使用Response对象的常用方法和属性访问其包含内容,代码如下。 import urllib.request response = urllib.request.urlopen('http://www.example.com/') # 获取 HTTP 响应状态码 print(response.code) # 获取 HTTP 响应头部信息 print(response.headers) # 获取 HTTP 响应的最终 URL print(response.url) # 读取响应内容并将其转换为字符串格式 html = response.read().decode('utf-8') print(html) # 读取响应内容中的前 100 个字节并将其转换为字符串格式 content = response.read(100).decode('utf-8') print(content) # 读取响应内容中的第一行并将其转换为字符串格式 line = response.readline().decode('utf-8') print(line) # 获取 HTTP 响应头部信息 headers = response.info() print(headers) # 获取指定名称头部的值 server = response.getheader('Server') print(server) # 获取所有头部信息 all_headers = response.getheaders() print(all_headers) 12 任务6-1:使用Urllib模块获取网页数据 壹 需要注意的是,每次调用read()方法或readline()方法都会从网络中读取数据,因此在处理大量数据时可能会比较慢。如果数据量较大,可以考虑分批读取。 (2)Request() 在Urllib库中,Request()函数用于构造HTTP请求,并返回一个类似请求的对象。通过这个对象,可以设置请求头、请求方法、请求参数等信息,并发送请求到指定的URL地址。通过这种方式,可以更好地控制HTTP请求的参数,以便与特定的API接口进行交互,并在代码中提高复用性。Request()函数语法格式如下所示。 urllib.request.Request(url, data=None, headers={}, method=None) 参数 描述 url 要访问的URL地址 data 要发送的数据,如果不需要发送数据,则该参数可省略,默认为None headers 请求头信息,为一个字典类型数据,默认为空字典,包含信息如下:User-Agent:客户端使用的操作系统和浏览器的名称和版本accept:浏览器端可以接受的媒体类型Accept-Encoding:编码方法Accept-Language:支持语言 method HTTP请求方法,常用方法如下:GET:获取网页POST:提交信息HEAD:获取头部信息PUT:提交信息,原信息被覆盖DELETE:提交删除请求 13 任务6-1:使用Urllib模块获取网页数据 壹 例如,使用Request()函数创建一个请求对象req,其中传入了URL地址和请求头信息,最后,使用urlopen()函数发送HTTP请求,并读取响应内容,代码如下。 import urllib.request url = 'http://www.example.com/' headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3'} req = urllib.request.Request(url, headers=headers) response = urllib.request.urlopen(req) html = response.read().decode('utf-8') print(html) 需要注意的是,在构造请求时需要确保请求方法和请求头信息是正确的,否则可能会导致请求失败或者服务器返回错误信息。 14 任务6-1:使用Urllib模块获取网页数据 壹 (3)urlencode() urllib.parse.urlencode(query, doseq=False, safe='', encoding=None, errors=None, quote_via=quote_plus) urlencode()是Python内置的一个URL编码函数,它主要用于将字典类型的数据编码为URL编码格式,并返回字符串类型的结果。URL编码是指将URL中的特殊字符转换为对应的ASCII码表示,以便于在不同的系统之间传输和识别。urlencode()函数语法格式如下所示。 参数说明见表。 参数 描述 query 需要进行编码的参数字典或者包含二元组的可迭代对象 doseq 当值为True时,会对字典中每个元素的值都进行编码;当值为False时,只对字典的键进行编码,默认为False safe 指定某些字符不需要进行编码,例如“-”、“.”等,默认为空字符串 encoding 指定编码方式,默认为utf-8 errors 指定编码错误处理方式,默认为“replace” quote_via 指定使用哪种编码方式,默认为quote_plus()函数 15 任务6-1:使用Urllib模块获取网页数据 壹 例如,使用urlencode()函数进行URL编码,代码如下。 import urllib.parse params = { 'name': 'Jack', 'age': '18', 'gender': 'male' } qs = urllib.parse.urlencode(params) print(qs) # 输出:name=Jack&age=18&gender=male 需要注意的是,urlencode()函数只能对参数进行编码,并不能对完整的URL进行编码。如果想对完整的URL进行编码,可以使用quote()函数或quote_plus()函数。 16 任务6-1:使用Urllib模块获取网页数据 壹 (4)urlretrieve() urllib.request.urlretrieve(url, filename=None, reporthook=None, data=None) urlretrieve()函数是一个HTTP文件下载工具,它可以方便地从网络上检索文件,并根据指定的URL地址将远程文件下载到本地,并保存为指定的文件,如图像、音频、视频、HTML页面、JSON数据等,语法格式如下所示。 参数说明见表。 参数 描述 url 要下载的文件的URL地址 filename 保存为本地文件时的名称,如果未指定,则使用URL中的文件名 reporthook 回调函数,用于显示下载进度和状态信息 data POST请求时需要传输的数据 17 任务6-1:使用Urllib模块获取网页数据 壹 import urllib.request url = 'https://www.python.org/static/img/python-logo.png' # 从URL检索图像,并将其存储到本地文件 urllib.request.urlretrieve(url, 'python-logo.png') 例如,使用urlretrieve()函数下载Python官网的Logo图片,并将其保存到当前目录下的python-logo.png文件中,代码如下。 需要注意的是,使用urlretrieve()函数进行文件下载时,程序会阻塞直到整个文件下载完成。如果需要异步下载文件,则需要使用多线程或异步IO技术。 18 任务6-1:使用Urllib模块获取网页数据 壹 2 error模块 error模块是Urllib的一个异常处理模块,它提供了一些与网络相关的异常类,用于在网络编程中捕获和处理异常,并提供更好的代码鲁棒性,在使用时需先导入import urllib.error。并且,error模块中包含了多个异常类,可以用来捕获常见的网络异常情况,如连接超时、DNS解析错误、HTTP错误等,error模块常用异常类见表。 异常类 描述 URLError 如果在访问URL时发生错误(如网络连接失败、DNS查询失败等),则会抛出URLError异常。URLError包含以下几个属性:reason:错误原因,可以是一个字符串或一个异常对象errno:错误号filename:URL对应的文件名,如果没有则为Noneargs:一个元组,包含其他额外的异常信息 HTTPError 在发送HTTP请求时,如果服务器返回了错误响应,则会抛出HTTPError异常。HTTPError是URLError的子类,包含以下几个属性:code:HTTP状态码reason:状态码对应的文本信息headers:响应头信息 ContentTooShortError 如果下载的内容长度小于指定长度,则会抛出ContentTooShortError异常。ContentTooShortError继承自URLError,包含以下几个属性:length:实际下载的内容长度expected_length:预期的内容长度 19 任务6-1:使用Urllib模块获取网页数据 壹 例如,在访问地址“http://www.example.com/”时做异常处理操作,如果遇到HTTP错误或URL错误,则捕获对应的异常并打印错误信息。如果没有遇到异常,则读取响应内容并输出,代码如下。 import urllib.request import urllib.error try: # 发送HTTP请求 response = urllib.request.urlopen('http://www.example.com/') except urllib.error.HTTPError as e: print('HTTPError:', e.code, e.reason) except urllib.error.URLError as e: print('URLError:', e.reason) else: # 读取响应内容并将其转换为字符串格式 html = response.read().decode('utf-8') print(html) 20 任务6-2 使用re模块过滤数据 贰 1 正则表达式 正则表达式由普通字符和特殊字符组成,其中,特殊字符也被称为元字符,它们具有特殊的含义;而除了特殊字符外,正则表达式中的所有字符都是普通字符,它们只匹配它们所代表的字面意思。正则表达式常用字符见表。 字符 描述 . 匹配任意单个字符,除了换行符 * 匹配前面的元素零次或多次 + 匹配前面的元素至少一次 ? 匹配前面的元素零次或一次 \ 用于转义下一个字符,例如:“\.”匹配一个点 ^ 匹配字符串开头 $ 匹配字符串结尾 [] 匹配其中任意一个字符,如“[abc]”匹配 a、b或c中的任意一个字符 [a-z] 匹配任意小写字母 [A-Z] 匹配任意大写字母 [0-9] 匹配任意数字 [^0-9] 匹配任意非数字字符 {n} 匹配n次 {n,} 匹配至少n次 {n,m} 匹配最少n次且最多m次 1、正则表达式字符 21 任务6-2 使用re模块过滤数据 贰 字符 描述 () 将多个元素组成一个整体进行匹配 | 匹配两个或多个分支中的任意一个。例如:“cat|dog”匹配cat或dog \d 匹配数字字符 \D 匹配非数字字符 \w 匹配字母、数字、下划线 \W 匹配非字母、数字、下划线 \b 匹配单词边界,即字与空格间的位置 \B 匹配非单词边界 \f 匹配换页符 匹配换行符 \r 匹配回车符 \t 匹配制表符 \s 匹配空白字符,包括空格、制表符、换页符 \S 匹配非空白字符 22 任务6-2 使用re模块过滤数据 贰 2、正则表达式字符优先级 01 02 03 04 05 转义符“\” 量词元字符“*”、“+”、“?”、“{m,n}”等 匹配任意单个字符元字符“.” 圆括号“()”、方括号“[]”、花括号“{}”和转换模式符“|” 锚定元字符“^”和“$” 字符集合“[]”中的范围表示符“-” 在正则表达式中,不同字符或元字符之间具有不同的优先级。当多个元字符出现在同一个正则表达式中时,它们按照优先级顺序进行匹配,一般来说,优先级高的元字符会优先匹配,然后再考虑优先级低的元字符。优先级顺序从高到低依次为: 23 任务6-2 使用re模块过滤数据 贰 2 re模块 在Python中,使用标准库模块re来支持正则表达式。该模块提供了许多函数,可以用于执行各种操作,例如匹配、搜索、替换等,常用函数见表。 函数 描述 compile() 编译正则表达式 match() 从字符串开头开始匹配正则表达式 search() 在字符串中搜索与正则表达式匹配的第一个内容 findall() 在字符串中查找所有与正则表达式匹配的内容 finditer() 在字符串中查找所有与正则表达式匹配的内容 sub() 将字符串中所有匹配正则表达式的内容替换为指定字符串 split() 将字符串按照正则表达式进行分割 24 任务6-2 使用re模块过滤数据 贰 (1)compile() compile()函数是re模块的基函数,主要用于对正则表达式的字符串形式进行编译,返回一个pattern对象,该对象可用于多次匹配操作,可以提高正则表达式的执行效率,语法格式如下所示。 re.compile(pattern, flags=0) 参数说明见表。 参数 描述 pattern 一个字符串形式的正则表达式 flags 一个可选的标志参数,用于指定正则表达式的匹配模式,可选值有:re.IGNORECASE/ re.I:忽略大小写进行匹配re.MULTILINE/ re.M:启用多行模式,在该模式下^和$会分别匹配行的开头和结尾re.DOTALL/ re.S:启用点号“.”匹配任何字符,包括换行符re.ASCII:仅匹配ASCII字符集re.UNICODE/ re.U:启用Unicode匹配re.VERBOSE/ re.X:启用详细模式,忽略正则表达式中的空白和注释,并允许使用 分隔正则表达式 25 任务6-2 使用re模块过滤数据 贰 例如,使用compile()函数将匹配一个或多个数字字符的正则表达式编译为对象regex,代码如下。 import re pattern = r'\d+' regex = re.compile(pattern) 需要注意的是,通过compile()编译的正则表达式对象可以多次使用,在效率方面具有优势。此外,如果需要在多个地方使用相同的正则表达式,可以预先编译成对象,避免反复编译的开销。 26 任务6-2 使用re模块过滤数据 贰 (2)match() match()函数是Python re模块中提供的一种用于匹配字符串的函数之一,它尝试从字符串的起始位置开始进行正则表达式的匹配,语法格式如下所示。 # pattern为正则表达式字符串 re.match(pattern, string, flags=0) # pattern为正则表达式对象 pattern.match(string, flags=0) 参数说明见表。 参数 描述 string 需要匹配的字符串 flags 用于指定正则表达式的匹配模式 27 任务6-2 使用re模块过滤数据 贰 例如,基于match()函数通过正则表达式判断一个字符串是否以数字开头,代码如下。 import re s = '123abc' m = re.match(r'\d+', s) if m: print('匹配成功') else: print('匹配失败') 28 任务6-2 使用re模块过滤数据 贰 需要注意的是,使用match()函数后,如果匹配成功,将返回一个Match对象,可以使用该对象的方法和属性获取匹配到的内容和位置信息;如果匹配失败,则返回None。Match对象方法和属性见表。 方法和属性 描述 group() 返回被匹配到的字符串 groups() 返回一个包含所有分组匹配的字符串的元组,如果没有捕获分组则返回空元组 groupdict() 返回一个包含所有具有名称的分组匹配的字典,键为分组名称,值为匹配到的字符串 start() 返回匹配的起始位置 end() 返回匹配的结束位置 span() 返回一个(start, end)元组,表示匹配字符串的起始位置和结束位置 29 任务6-2 使用re模块过滤数据 贰 例如,基于match()函数通过正则表达式判断一个字符串是否以数字开头,并获取匹配的结果,代码如下。 import re s = '123abc' m = re.match(r'\d+', s) if m: print('匹配成功') print(m.group()) # 输出 '123' print(m.start()) # 输出 0 print(m.end()) # 输出 3 else: print('匹配失败') 需要注意的是,当使用正则表达式进行分组匹配时,group()、start()和end()等方法默认返回第一个分组的匹配结果,如果要获取其他分组的匹配结果,可以通过指定分组的索引或名称来获取。例如,group(1)和group(2)分别表示第1个和第2个分组的匹配结果。 30 任务6-2 使用re模块过滤数据 贰 (3)search() search()函数,用于在字符串中搜索并返回第一个匹配正则表达式的位置。并且,search()函数在使用时与match()函数相同。与match()函数不同之处在于,search()函数会扫描整个字符串,并返回一个Match对象,如果没有找到匹配,则返回None。 例如,基于search()函数通过正则表达式判断一个字符串是否以数字开头,并获取匹配的结果,代码如下。 import re s = 'abc123def' m = re.search(r'\d+', s) if m: print('匹配成功') print(m.group()) # 输出 '123' else: print('匹配失败') 需要注意的是,search()函数会扫描整个字符串,因此比match()函数的效率更低。如果只需在字符串开头进行匹配,则应该使用match()函数。 31 任务6-2 使用re模块过滤数据 贰 (4)findall() 相比于search()函数和match()函数,findall()函数可以在整个字符串中搜索符合正则表达式模式的所有子串,并以列表的形式返回匹配结果,其中每个元素是一个匹配到的非重叠子串,适用于查找多个匹配结果的情况。并且,使用方式与search()函数和match()函数相同。 例如,基于findall()函数通过正则表达式寻找字符串中所有的数字,并获取匹配的结果,代码如下。 import re s = 'a1b2c3d4' lst = re.findall(r'\d+', s) print(lst) # 输出 ['1', '2', '3', '4'] 需要注意的是,findall()函数会扫描整个字符串,因此比search()方法的效率更低。如果只需查找第一个匹配的子串,则应该使用search()方法。 32 任务6-2 使用re模块过滤数据 贰 (5)finditer() finditer()函数功能与findall()函数基本相同,同样用于在字符串中查找所有匹配正则表达式的子串,不同之处在于,finditer()函数会返回一个通过迭代器逐个生成的Match对象序列。 例如,基于finditer()函数通过正则表达式寻找字符串中所有的数字,并使用迭代器获取匹配的结果,代码如下。 import re s = 'a1b2c3d4' it = re.finditer(r'\d+', s) for m in it: print(m.group()) # 逐一输出匹配的子串 33 任务6-2 使用re模块过滤数据 贰 (6)sub() 在re模块中,sub()是一种用于搜索并替换字符串的函数,可以在字符串中查找所有匹配正则表达式的子串,并替换为指定的字符串后,返回替换后的新字符串,语法格式如下所示。 re.sub(pattern, repl, string, count=0, flags=0) pattern.sub(repl, string, count=0, flags=0) 参数说明见表。 参数 描述 repl 用于替换的字符串 string 需要进行搜索和替换的原始字符串 count 最多替换次数 flags 用于指定正则表达式的匹配模式 34 任务6-2 使用re模块过滤数据 贰 例如,基于sub()函数通过正则表达式将字符串中的数字替换为“x”,代码如下。 import re s = 'a1b2c3d4' s_new = re.sub(r'\d', 'x', s) print(s_new) # 输出 'axbxcdx' 35 任务6-2 使用re模块过滤数据 贰 (7)split() split()是Python re模块中提供的一种用于分割字符串的函数,该函数可以按照正则表达式匹配的位置,将字符串分割为多个子串,并返回一个列表,语法格式如下所示。 re.split(pattern, string, maxsplit=0, flags=0) pattern.split(string, maxsplit=0, flags=0) 参数说明见表。 参数 描述 string 需要进行分割的字符串 maxsplit 最大分割次数 flags 用于指定正则表达式的匹配模式 例如,基于split()函数通过正则表达式将字符串按照空格和逗号进行分割,代码如下。 import re s = 'a b,c,d e' lst = re.split(r'[ ,]+', s) print(lst) # 输出 ['a', 'b', 'c', 'd', 'e'] 36 任务6-3 使用PyMySQL模块存储数据 叁 1 PyMySQL模块安装 1、PyMySQL模块简介 使用PyMySQL,可以在Python中连接、查询和操作MySQL数据库。并且,PyMySQL 完全遵循Python数据库API v2.0规范,因此可以与许多Python数据库应用程序和框架集成。PyMySQL的主要功能包括: 创建 MySQL 数据库连接对象 执行 SQL 查询和更新语句 获取查询结果,并进行数据处理和转换 支持事务处理和批量操作 提供安全的连接和身份验证机制,以保护数据库的安全性 进行错误处理和日志记录,以帮助开发人员调试和优化应用程序 具有良好的可扩展性和灵活性,以满足不同应用场景的需求 37 任务6-3 使用PyMySQL模块存储数据 叁 并且,相比其他的Python MySQL库,PyMySQL具有的优点如下: 纯Python编写,无需安装额外的C扩展或库依赖 兼容Python DB API 2.0规范,易于学习和使用 支持大多数MySQL特性,如存储过程、视图和触发器等 在网络连接上表现良好,通过预处理SQL语句可以有效地防止SQL注入攻击 代码简单,易于定制和维护 38 任务6-3 使用PyMySQL模块存储数据 叁 2、PyMySQL模块安装 由于PyMySQL是Python的第三方模块,因此可以直接使用pip命令进行安装,效果如图所示。 39 任务6-3 使用PyMySQL模块存储数据 叁 注意,如果使用pip安装失败,可以通过下载源码方式进行安装,源码地址“https://github.com/PyMySQL/PyMySQL” 安装成功后,即可进入Python客户端,通过引入PyMySQL模块进行验证,效果如图所示。 40 任务6-3 使用PyMySQL模块存储数据 叁 2 数据库连接 1、PyMySQL模块简介 在使用PyMySQL对MySQL数据库进行操作之前,创建数据库连接对象是比不可少的一步。在PyMySQL中,可以通过connect()函数来创建数据库连接对象,方法的参数包括MySQL服务器的连接配置信息,语法格式如下所示。 pymysql.connect(host='localhost',user='',password='',database=None,port=3306,charset='utf8mb4') 参数说明见表。 参数 描述 host 数据库服务器地址,默认为localhost user 数据库用户名 password 数据库密码 database 要连接的数据库名称,默认为 None port 数据库端口号,默认为3306 charset 字符集编码格式,默认为utf8mb4 41 任务6-3 使用PyMySQL模块存储数据 叁 例如,使用connect()函数创建一个MySQL数据库连接对象,并指定要连接的主机、用户名、密码、数据库名、端口号和字符集等信息,代码如下。 import pymysql # 创建 MySQL 数据库连接对象 conn = pymysql.connect( host='localhost', user='root', password='123456', database='testdb', port=3306, charset='utf8mb4' ) 42 任务6-3 使用PyMySQL模块存储数据 叁 需要注意的是,在完成与MySQL数据库的交互后,应该关闭连接,以避免资源浪费和安全问题。在PyMySQL中,可以调用连接对象的close()方法实现连接的关闭。 例如,使用close()方法关闭MySQL数据库连接,代码如下。 # 关闭数据库连接 conn.close() 43 任务6-3 使用PyMySQL模块存储数据 叁 3 数据库连接对象方法 在PyMySQL中,创建MySQL数据库连接对象后,除了可以使用close()方法实现连接的关闭外,连接对象还提供了多个管理数据库的方法,可以在Python代码中对MySQL数据库进行操作,常用方法见表。 方法 描述 cursor() 创建一个游标对象 commit() 提交当前事务,该方法只对支持事务的数据库生效 44 任务6-3 使用PyMySQL模块存储数据 叁 (1)cursor() 游标是一种与数据库交互的方式,它能够在查询结果集中向前和向后移动,并把指针指向不同的记录。目前,PyMySQL中提供了cursor()方法,能够创建一个用于执行SQL命令并处理查询结果的游标对象,语法格式如下所示。 cursor = conn.cursor(cursor=None) 参数说明见表。 参数 描述 conn PyMySQL连接对象 cursor 要使用的游标类型,可选值有:pymysql.cursors.Cursor:普通的游标对象,默认创建的游标对象pymysql.cursors.SSCursor:不缓存游标,主要用于当操作需要返回大量数据的时候pymysql.cursors.DictCursor:以字典的形式返回操作结果pymysql.cursors.SSDictCursor:不缓存游标,将结果以字典的形式进行返回pymysql.cursors.TupleCursor:以元组的形式返回操作结果 45 任务6-3 使用PyMySQL模块存储数据 叁 例如,使用cursor()方法创建一个游标对象,代码如下。 import pymysql # 连接数据库 conn = pymysql.connect( host='localhost', user='root', password='123456', database='testdb', port=3306, charset='utf8mb4' ) # 获取Cursor对象 cursor = conn.cursor() 46 任务6-3 使用PyMySQL模块存储数据 叁 (2)commit() 在PyMySQL中,commit()方法用于提交当前事务。通常使用在数据修改操作(如INSERT、UPDATE和DELETE)执行后,以保证数据的一致性,如果不调用commit()方法提交事务,则数据库不会保存这些修改。commit()方法语法格式如下所示。 conn.commit() 47 任务6-3 使用PyMySQL模块存储数据 叁 4 游标对象方法 PyMySQL游标对象提供了一些用于管理MySQL数据库查询结果的方法,这些方法可以帮助开发人员更好地处理查询结果集,常用方法见表。 方法 描述 execute() 执行SQL语句 executemany() 执行多条SQL语句 fetchmany() 获取结果集中的指定数量的行数据 fetchall() 获取结果集中的所有行数据 48 任务6-3 使用PyMySQL模块存储数据 叁 (1)execute() 在PyMySQL中,Cursor对象的execute()方法用于执行一条SQL语句,它可以执行任何一种SQL语句(包括添加、查询、更新和删除等),返回值为受影响的行数(针对更新、删除操作),或者 None(针对查询操作),语法格式如下所示。 cursor.execute(sql, args=None) 参数说明见表。 参数 描述 cursor PyMySQL游标对象 sql 要执行的SQL语句 args 查询时所需的参数,它可以是单个参数或者一个元组、列表等可迭代对象 49 任务6-3 使用PyMySQL模块存储数据 叁 例如,使用execute()方法向数据库中插入一条数据,代码如下。 sql = 'INSERT INTO `table` (`name`, `age`) VALUES (%s, %s)' cursor.execute(sql, ('Tom', 18)) # 提交事务 conn.commit() (2)executemany() 相比与execute()方法,executemany()用于批量执行相同的SQL语句,可以一次性执行多个SQL语句,通常用于批量插入或更新数据,语法格式如下所示。 cursor.executemany(sql, args_list) 50 任务6-3 使用PyMySQL模块存储数据 叁 参数说明见表。 参数 描述 cursor PyMySQL游标对象 sql 要执行的SQL语句 args_list 一个元组或列表的列表,每个元组或列表代表一组参数 例如,使用executemany()方法向数据库中批量插入多条数据,代码如下。 sql = 'INSERT INTO `table` (`name`, `age`) VALUES (%s, %s)' data = [('Tom', 18), ('Jerry', 20), ('Mike', 22)] cursor.executemany(sql, data) # 提交事务 connection.commit() 需要注意的是,在批量插入或更新数据时,由于数据量可能非常大,因此需要考虑分批提交数据以保证程序的稳定性和效率。同时,在执行过程中,如果出现异常需要进行异常处理,例如使用try-except语句块来捕获异常并回滚事务以保证数据的一致性。 51 任务6-3 使用PyMySQL模块存储数据 叁 (3)fetchmany() 在PyMySQL中,Cursor对象的fetchmany()方法用于获取指定数量的查询结果,它可以一次性获取指定数量的记录,适用于查询结果较大的情况,语法格式如下所示。 cursor.fetchmany(size=None) 参数说明见表。 参数 描述 cursor PyMySQL游标对象 size 表示要获取的查询结果数量,如果不指定size,则默认为Cursor对象的数组大小,可以通过设置cursor.arraysize属性来改变其大小。cursor.arraysize属性是一个整数类型的属性,表示默认情况下一次从数据库中获取的查询结果数量 52 任务6-3 使用PyMySQL模块存储数据 叁 例如,使用fetchmany()方法获取查询结果集的前10行数据,代码如下。 sql = 'SELECT `name`, `age` FROM `table`' cursor.execute(sql) result = cursor.fetchmany(10) print(result) 需要注意的是,在使用fetchmany()方法时需要先执行查询操作,确保结果集已经准备就绪。同时,在获取结果集时也需要考虑到内存占用的问题,尽量避免一次性获取过多的数据,以免出现内存溢出等问题。 53 任务6-3 使用PyMySQL模块存储数据 叁 (4)fetchall() fetchall()方法用于获取查询结果集的所有数据,可以一次性获取所有的记录,并返回一个元组列表,每个元组表示一行记录,列表中的行序按执行查询语句得出的结果集顺序排列;当结果集中所有行都被获取时,fetchall()方法将返回一个空列表,适用于查询结果较小的情况,语法格式如下所示。 cursor.fetchall() 例如,使用fetchall()方法获取查询结果集的所有数据,代码如下。 sql = 'SELECT `name`, `age` FROM `table`' cursor.execute(sql) result = cursor.fetchall() print(result) 54 $$

资源预览图

项目6 使用Python模块(课件)-《Python程序设计》同步教学(机工教育版)
1
项目6 使用Python模块(课件)-《Python程序设计》同步教学(机工教育版)
2
项目6 使用Python模块(课件)-《Python程序设计》同步教学(机工教育版)
3
项目6 使用Python模块(课件)-《Python程序设计》同步教学(机工教育版)
4
项目6 使用Python模块(课件)-《Python程序设计》同步教学(机工教育版)
5
项目6 使用Python模块(课件)-《Python程序设计》同步教学(机工教育版)
6
由于学科网是一个信息分享及获取的平台,不确保部分用户上传资料的 来源及知识产权归属。如您发现相关资料侵犯您的合法权益,请联系学科网,我们核实后将及时进行处理。