0%

问题

在Ubuntu22.04系统中,使用命令 sudo apt updatesudo apt install mysql-server 可以成功安装MySQL数据库。但是随之而来有一个问题:

在安装的过程中,我并没有设置密码,使用命令 sudo systemctl start mysqlmysql -u root -p后,无论输入什么密码,都无法正常登录。

通过询问通义千文以及查阅多方资料,通过以下方案可以成功设置root密码。且经过尝试,如果遗忘了root密码,该方案也可以帮助重新设置其密码。

解决方案

停止MySQL服务

为了后续操作,我们需要首先停止正在运行的MySQL服务。

1
sudo systemctl stop mysql

以跳过权限表检查的方式启动Mysql服务

通常在登录 MySQL 时,MySQL 会进行一系列权限表的验证来进行用户身份认证。

在这里,以跳过权限表检查的方式启动MySQL,这样就可以无需密码直接登录。

1
sudo mysql_safe --skip-grant-tables &

另起命令行窗口,登录 MySQL

由于已经跳过了权限表检查,现在可以直接以 root 用户身份登录 MySQL,无需密码。

1
mysql -u root

选择 mysql 数据库

登录后,需要选择 mysql 数据库,因为用户的账号信息存储在这个数据库中。

1
mysql> use mysql;

检查 root 用户的认证插件和密码

查询 mysql.user 数据表中存放的用户账号、密码和认证插件信息,方便后续操作。

1
mysql> select user, plugin, authentication_string from mysql.user;

根据情况更换用户认证插件

通过查询发现,我原有的用户认证插件是 auth_socket ,这意味着 MySQL 正在使用 UNIX socke t的 peer 认证方式。在这种方式下 ,MySQL 直接通过操作系统级别的身份验证来确认连接请求,而不是基于密码。而且,这种方式通常用于 localhost 上的连接,并且不需要密码。

但是,我需要使用密码进行用户认证,因此认证插件要切换成 mysql_native_password 或者 caching_sha2_password。这里使用 caching_sha2_password 作为认证插件。

1
mysql> update user set plugin="caching_sha2_password" where user='root';  

设置密码为空

由于我所选择的认证插件为 caching_sha2_password ,存储在 mysql.user 表中的密码是通过加密算法加密后的密码。因此,这里我先设置密码为空,等之后以 root 密码登录之后,再更换密码。

1
mysql> update user set authentication_string='' where user='root';

退出MySQL

1
EXIT;

正常启动 MySQL 服务

关闭跳过权限检查的MySQL实例,然后正常启动MySQL服务。

1
2
sudo systemctl stop mysql
sudo systemctl start mysql

以 root 密码认证正常登录

当mysql要求输入密码时,直接按 enter 键,表示密码为空。

1
mysql -u root -p

设置正式密码

现在MySQL应该以正常模式运行了,可以使用 ALTER USER 命令设置正式的 caching_sha2_password 类型的密码, 记得将命令中的 new_password更改为正式的密码。

1
2
3
mysql> alter user 'root'@'localhost' identified with caching_sha2_password by 'new_password';

mysql> FLUSH PRIVILEGES;

总结

整个解决方案看起来比较繁琐,一是因为在 --skip-grant-tables 这种跳过权限表检查的情况下,无法直接使用 ALTER USER 命令来更换 root 的密码;二是因为我自身想要使用 caching_sha2_password 作为认证插件,所以无法直接用 update的方式来显示的方式来更改密码。

如果有更好的解决方案,欢迎交流!

前言

关于爬虫的教程网络上满天飞,我想,这应该是由于它极大地有利于信息资源的收集和分析。简单来说,在Python中,有许多大佬编写的基本库,我们可以使用这些库中的许多函数和方法,发送HTTP请求。

怎样通过 urllib库 发送 HTTP 请求?

什么是 urllib? 字面意思,即关于url的一个lib。作为一个Python的内置的HTTP请求库urlllib提供了一些可以通过URL访问各种信息资源的函数

urllib库主要由四个模块组成:

1. 使用urllib.parse解析URL

  • 使用urlparse()分段URL
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
        # 导入工具包
    from urllib.parse import urlparse

    # 使用urlparse()函数解析URL
    result = urlparse('https://docs.python.org/3/library/urllib.parse.html#url-parsing')

    # 输出解析结果
    print(type(result))
    print(result)
    ```
    在这里,我们用`urlparse()`函数构建了一个**实例对象**(ParseResult类型),并将其赋值给`result`,以便调用。

    事实上,**ParseResult类型**对象包含6个部分:
    - **scheme**,代表**协议**,通常在"://"前面,这里即`http`
    - **netloc**,代表**域名**,通常在第一个"/"前面,这里即`docs.python.org:80`
    - **path**,代表**访问路径**,通常在域名之后,这里即`/3/library/urllib.parse.html`
    - **params**,代表**参数**,通常在"?"之前,这里不存在
    - **query**,代表**查询条件**,通常在"?"之后,这里也不存在
    - **fragment**,代表**瞄点**,通常在"#"之后,用于直接定位页面内部的下拉位置,这里即`url-parsing`

    - 使用`urlunparse()`构造URL
    ```python
    # 导入工具包
    from urllib.parse import urlunparse

    # 构建列表行参数
    data = ['http','www.baidu.com','index.html','user','a=6','comment']
    # 构造完整的URL,并打印
    print(urlunparse(data))
    事实上,在urllib.parse中,解析URL的方法不仅有urlparse()函数,还有urlsplit()等;构造URL的方法不仅有urlunparse()函数,还有urlunspliturlencode()等。

2. 使用urllib.request打开 URL,模拟发送请求

  • 使用urllib.request.urlopen函数发送HTTP请求,构造对象

    1
    2
    3
    4
    5
    6
    7
    8
    # 导入工具包  
    import urllib.request

    # 使用`urlopen`函数发送HTTP请求
    response = urllib.request.urlopen('https://www.baidu.com')

    # 打印网页源代码
    print(response.read().decode('utf-8'))

    urllib.request.urlopen 函数构造一个接受请求的实例对象(HTTPResponse类型),并将其赋值给response变量,以便之后使用。

    read()方法可以得到返回的网页内容。事实上,HTTPResponse类型的对象,不仅可以调用read()getheaders()方法,还可以调用statusmsg属性来查看请求发送后返回的一系列信息。

  • 通过Request类灵活配置参数,构建请求信息对象

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    # 导入工具包
    import urllib.request

    # 设置url、headers等参数
    url = 'http://httpbin.org/post'
    headers = {
    'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36',
    'Host':'httpbin.org'
    }

    # 集合请求参数,独立成对象
    req = request.Request(url=url,headers=headers,method='POST')

    # 发送HTTP请求
    response = request.urlopen(req)

    # 打印
    print(response.read().decode('utf-8'))

    这里我们依然使用urlopen()方法来发送HTTP请求,但是传递的不再是单纯的URL,而是一个Request类型的对象。通过集合各种参数,将其独立成一个对象,可以更加丰富和灵活地配置参数。

    这里的headers即为请求头,method即为请求方法

  • 使用Handler处理器进行高级操作(以Cookies处理为例)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    # 导入工具包
    import urllib.request
    import http.cookiejar

    # 声明一个CooieJar对象
    cookie = http.cookiejar.Cookiejar()

    # 构建一个专门处理Cookies的对象
    handler = urllib.request.HTTPCookieProcessor(cookie)

    # 构建一个Opener对象
    opener = urllib.request.build_opener(handler)

    # 通过open()方法打开链接
    response = opener.open('https://www.baidu.com')

    # 查看每条Cookie的名称和值
    for item in cookie:
    print(item.name+'='+item.value)

    HTTPCookieProcessorurllib.request模块里用于处理Cookie的一个类。值得注意的是这里打开链接的不再是request.urlopen()函数,而是用Opener对象的open()方法来发出请求。

3. 使用urllib.error捕捉请求错误,进行异常处理

  • 使用URLError类捕捉URL异常

    1
    2
    3
    4
    5
    6
    7
    8
    9
    # 导入工具包
    from urllib import request, error

    # 使用try块,捕捉可能的异常
    try:
    response = request.urlopen('https://baidu.com')
    # 将异常对象赋值给变量e
    except error.URLError as e:
    print(e.reason)

    在这里如果发生网页不存在等请求异常,我们就可以通过URLError捕捉异常,从而避免程序的异常终止

  • 使用HTTPError类捕捉HTTP请求错误

    1
    2
    3
    4
    5
    6
    7
    8
    # 导入工具包
    from urllib import request, error

    # 用try块捕捉可能的错误
    try:
    response = request.urlopen('http://baidu.com')
    except error.HttpError as e:
    print(e.reason, e.code, e.headers, seq='\n')

参考资料

urllib - URL handling modules. Python官方文档
Python3网络爬虫开发实战教程. 崔庆才

Welcome to Hexo! This is your very first post. Check documentation for more info. If you get any problems when using Hexo, you can find the answer in troubleshooting or you can ask me on GitHub.

Quick Start

Create a new post

1
$ hexo new "My New Post"

More info: Writing

Run server

1
$ hexo server

More info: Server

Generate static files

1
$ hexo generate

More info: Generating

Deploy to remote sites

1
$ hexo deploy

More info: Deployment