【Web Crawler】Python 的 urllib.request 用于 HTTP 请求

如果您需要使用 Python 发出 HTTP 请求,那么您可能会发现自己被引导至 brilliantrequests库。尽管它是一个很棒的库,但您可能已经注意到它并不是 Python 的内置部分。如果您出于某种原因更喜欢限制依赖项并坚持使用标准库 Python,那么您可以使用urllib.request!

在本教程中,您将:

  • 了解如何发出基本的HTTP 请求urllib.request

  • 深入了解HTTP 消息的具体细节及其urllib.request表示方式

  • 了解如何处理HTTP 消息的字符编码

  • 探索使用时的一些常见错误urllib.request并学习如何解决它们

  • 将您的脚趾浸入经过身份验证的请求的世界urllib.request

  • 理解为什么两者urllib和requests库都存在以及何时使用其中一个或另一个

如果您听说过 HTTP 请求,包括GETPOST,那么您可能已经准备好学习本教程了。此外,您应该已经使用 Python读取和写入文件,最好使用上下文管理器,至少一次。

最终,您会发现提出请求不一定是令人沮丧的经历,尽管它确实有这样的名声。您经常遇到的许多问题都是由于 Internet 这个奇妙事物的内在复杂性造成的。好消息是该urllib.request模块可以帮助揭开这种复杂性的神秘面纱。

了解更多信息: 单击此处与 290,000 多名 Python 开发人员一起阅读 Real Python Newsletter ,获取新的 Python 教程和新闻,让您成为更高效的 Pythonista。

基本 HTTP GET 请求urllib.request

在深入了解什么是 HTTP 请求及其工作原理之前,您需要通过向示例 URL发出基本的 GET 请求来了解一下。您还将向模拟REST API发出 GET 请求以获取某些JSON数据。如果您想了解 POST 请求,一旦您对urllib.request.

Beware:根据您的具体设置,您可能会发现其中一些示例不起作用。如果是这样,请跳到有关常见 urllib.request 错误 的部分以进行故障排除。如果您遇到此处未涵盖的问题,请务必在下面使用精确且可重现的示例进行评论。

首先,您将向 发出请求www.example.com,服务器将返回一条 HTTP 消息。确保您使用的是 Python 3 或更高版本,然后使用urlopen()函数 from urllib.request

from urllib.request import urlopen
with urlopen("https://www.example.com") as response:
    body = response.read()

body[:15]

b''

在此示例中,您urlopen()urllib.request. 使用上下文管理器 with,您可以发出请求并接收响应urlopen()。然后您读取响应的主体并关闭响应对象。这样,您就可以显示正文的前十五个位置,并指出它看起来像一个 HTML 文档。

你在这!您已成功发出请求,并收到了回复。通过检查内容,您可以判断它很可能是一个 HTML 文档。请注意,正文的打印输出前面有b。这表示一个bytes literal,您可能需要对其进行解码。在本教程的后面,您将学习如何将字节转换为字符串、将它们写入文件或将它们解析为字典

如果您要调用 REST API 以获取 JSON 数据,则该过程仅略有不同。在下面的示例中,您将向{JSON}Placeholder请求一些虚假的待办事项数据:

from urllib.request import urlopen
import json
url = "https://jsonplaceholder.typicode.com/todos/1"
with urlopen(url) as response:
    body = response.read()

todo_item = json.loads(body)
todo_item

{'userId': 1, 'id': 1, 'title': 'delectus aut autem', 'completed': False}

在此示例中,您所做的与上一个示例中的操作几乎相同。但在这一个中,您导入urllib.request and json,使用json.loads()函数 withbody将返回的 JSON 字节解码和解析为Python 字典。瞧!

如果您足够幸运能够使用无错误的端点,例如这些示例中的端点,那么也许以上就是您需要的全部urllib.request。话又说回来,您可能会发现这还不够。

现在,在进行一些urllib.request故障排除之前,您将首先了解 HTTP 消息的底层结构并了解如何urllib.request处理它们。这种理解将为解决许多不同类型的问题提供坚实的基础。

HTTP 消息的具体细节

要了解您在使用 时可能遇到的一些问题,您urllib.request需要检查响应是如何由 表示的urllib.request。为此,您将受益于对HTTP 消息是什么的高级概述,这就是您将在本节中获得的内容。

在进行高级概述之前,先简要说明一下参考来源。如果您想深入了解技术领域,互联网工程任务组 (IETF)有大量的征求意见 (RFC)文档。这些文档最终成为 HTTP 消息之类的实际规范。例如, RFC 7230,第 1 部分:消息语法和路由都是关于 HTTP 消息的。

如果您正在寻找比 RFC 更容易理解的参考资料,那么Mozilla 开发者网络 (MDN)有大量参考文章。例如,他们关于HTTP 消息的文章虽然仍然是技术性的,但更容易理解。

现在您已经了解了这些基本的参考信息来源,在下一节中您将对 HTTP 消息有一个初学者友好的概述。

了解什么是 HTTP 消息

简而言之,HTTP 消息可以理解为文本,以字节流的形式传输,其结构遵循 RFC 7230 指定的准则。解码后的 HTTP 消息可以像两行一样简单:

GET / HTTP/1.1
Host: www.google.com

这使用协议在根 ( )指定GET请求。唯一需要的标头是主机,. 目标服务器有足够的信息来使用此信息做出响应。/HTTP/1.1www.google.com

响应在结构上类似于请求。HTTP 消息有两个主要部分,元数据正文。在上面的请求示例中,消息是没有正文的所有元数据。另一方面,响应确实有两个部分:

HTTP/1.1 200 OK
Content-Type: text/html; charset=ISO-8859-1
Server: gws
(... other headers ...)

响应以指定 HTTP 协议和状态的状态行开始。在状态行之后,你会得到许多键值对,例如,代表所有的响应。这是响应的元数据。HTTP/1.1200 OKServer: gws

在元数据之后,有一个空行,用作标题和正文之间的分隔符。空行之后的所有内容构成主体。这是您在使用urllib.request.

注意:空行在技术上通常称为 换行符 。HTTP 消息中的换行符必须是 Windows 样式的 回车符 ( \r ) 和 行尾 符( \n )。在 类 Unix 系统上,换行符通常只是一个行尾 ( \n )。

您可以假定所有 HTTP 消息都遵循这些规范,但有些消息可能会违反这些规则或遵循旧规范。不过,这很少会引起任何问题。因此,请将其牢记在心,以防遇到奇怪的错误!

在下一节中,您将了解如何urllib.request处理原始 HTTP 消息。

了解如何urllib.request表示 HTTP 消息

使用时您将与之交互的 HTTP 消息的主要表示urllib.requestHTTPResponse对象。urllib.request模块本身依赖于低级http模块,您不需要直接与之交互。不过,您确实最终会使用一些提供的数据结构http,例如HTTPResponseHTTPMessage

注意:在 Python 中表示 HTTP 响应和消息的对象的内部命名可能有点混乱。您通常只与 的实例进行交互HTTPResponse ,而请求端则在内部处理。
您可能认为这HTTPMessage 是一种HTTPResponse 继承自的基类,但事实并非如此。HTTPResponse 直接继承自io.BufferedIOBase ,而HTTPMessage 类继承自 email.message.EmailMessage
在源代码中将其EmailMessage 定义为包含一堆标头和有效负载的对象,因此它不一定是电子邮件。HTTPResponse 仅用HTTPMessage 作其标头的容器。
但是,如果您谈论的是 HTTP 本身而不是它的 Python 实现,那么您将 HTTP 响应视为一种 HTTP 消息是正确的。

当您使用 发出请求时urllib.request.urlopen(),您会得到一个HTTPResponse对象作为回报。花一些时间探索HTTPResponse对象pprint()dir()查看属于它的所有不同方法和属性:

from urllib.request import urlopen
from pprint import pprint
with urlopen("https://www.example.com") as response:
    pprint(dir(response))

要显示此代码片段的输出,请单击以展开下面的可折叠部分:

['__abstractmethods__',
 '__class__',
 '__del__',
 '__delattr__',
 '__dict__',
 '__dir__',
 '__doc__',
 '__enter__',
 '__eq__',
 '__exit__',
 '__format__',
 '__ge__',
 '__getattribute__',
 '__gt__',
 '__hash__',
 '__init__',
 '__init_subclass__',
 '__iter__',
 '__le__',
 '__lt__',
 '__module__',
 '__ne__',
 '__new__',
 '__next__',
 '__reduce__',
 '__reduce_ex__',
 '__repr__',
 '__setattr__',
 '__sizeof__',
 '__str__',
 '__subclasshook__',
 '_abc_impl',
 '_checkClosed',
 '_checkReadable',
 '_checkSeekable',
 '_checkWritable',
 '_check_close',
 '_close_conn',
 '_get_chunk_left',
 '_method',
 '_peek_chunked',
 '_read1_chunked',
 '_read_and_discard_trailer',
 '_read_next_chunk_size',
 '_read_status',
 '_readall_chunked',
 '_readinto_chunked',
 '_safe_read',
 '_safe_readinto',
 'begin',
 'chunk_left',
 'chunked',
 'close',
 'closed',
 'code',
 'debuglevel',
 'detach',
 'fileno',
 'flush',
 'fp',
 'getcode',
 'getheader',
 'getheaders',
 'geturl',
 'headers',
 'info',
 'isatty',
 'isclosed',
 'length',
 'msg',
 'peek',
 'read',
 'read1',
 'readable',
 'readinto',
 'readinto1',
 'readline',
 'readlines',
 'reason',
 'seek',
 'seekable',
 'status',
 'tell',
 'truncate',
 'url',
 'version',
 'will_close',
 'writable',
 'write',
 'writelines']

这是很多方法和属性,但您最终只会使用其中的一小部分。除此之外.read(),重要的通常涉及获取有关标头的信息。

检查所有标头的一种方法是访问对象的.headers属性HTTPResponse。这将返回一个HTTPMessage对象。方便地,您可以HTTPMessage通过调用.items()它来将所有标头作为元组来对待它,就像字典一样:

with urlopen("https://www.example.com") as response:
    pass

response.headers
pprint(response.headers.items())
[('Accept-Ranges', 'bytes'), 
('Age', '398424'), 
('Cache-Control', 'max-age=604800'),
('Content-Type', 'text/html; charset=UTF-8'), 
('Date', 'Tue, 25 Jan 2022 12:18:53 GMT'), 
('Etag', '"3147526947"'),
('Expires', 'Tue, 01 Feb 2022 12:18:53 GMT'), 
('Last-Modified', 'Thu, 17 Oct 2019 07:18:26 GMT'), 
('Server', 'ECS (nyb/1D16)'), ('Vary', 'Accept-Encoding'), 
('X-Cache', 'HIT'), 
('Content-Length', '1256'), 
('Connection', 'close')]

现在您可以访问所有响应标头了!您可能不需要这些信息中的大部分,但请放心,某些应用程序确实会用到它。例如,您的浏览器可能会使用标头来读取响应、设置 cookie 并确定适当的缓存生存期。

有一些方便的方法可以从HTTPResponse对象中获取标头,因为这是很常见的操作。您可以.getheaders()直接调用该HTTPResponse对象,它将返回与上面完全相同的元组列表。如果您只对一个标题感兴趣,比如Server标题,那么您可以使用单数.getheader("Server")onHTTPResponse或使用方括号 ( []) 语法 on .headersfrom HTTPMessage

>>> response.getheader("Server")
'ECS (nyb/1D16)'
>>> response.headers["Server"]
'ECS (nyb/1D16)'

说实话,您可能不需要像这样直接与标题进行交互。您最可能需要的信息可能已经有一些内置的辅助方法,但现在您知道了,以防您需要更深入地挖掘!

关闭一个HTTPResponse

该对象与文件对象HTTPResponse有很多共同之处。类继承自,文件对象也是如此,这意味着您必须注意打开和关闭。HTTPResponseIOBase

在简单的程序中,如果您忘记关闭HTTPResponse对象,您不太可能注意到任何问题。但是,对于更复杂的项目,这会显着降低执行速度并导致难以查明的错误。

出现问题是因为输入/输出(I/O) 流是有限的。每个都HTTPResponse需要在读取时保持流清晰。如果您从不关闭您的流,这最终将阻止任何其他流被打开,并且它可能会干扰其他程序甚至您的操作系统。

所以,一定要关闭你的HTTPResponse对象!为方便起见,您可以使用上下文管理器,如您在示例中所见。您还可以通过显式调用.close()响应对象来获得相同的结果:

from urllib.request import urlopen
response = urlopen("https://www.example.com")
body = response.read()
response.close()

在此示例中,您不使用上下文管理器,而是显式关闭响应流。不过,上面的示例仍然存在问题,因为在调用 之前可能会引发异常.close(),从而阻止正确的拆解。为了使这个调用成为无条件的,就像它应该的那样,你可以使用带有一个和一个子句的tryexcept块:elsefinally

from urllib.request import urlopen
response = None
try:
    response = urlopen("https://www.example.com")
except Exception as ex:
    print(ex)
else:
    body = response.read()
finally:
    if response is not None:
        response.close()

.close()在此示例中,您通过使用块实现了对 的无条件调用,finally无论是否引发异常,该块都将始终运行。块中的代码finally首先检查response对象是否存在is not None,然后将其关闭。

也就是说,这正是 aa 上下文管理器所做的,并且with语法通常是首选的。语法不仅with更简洁、更易读,而且还可以保护您免受讨厌的遗漏错误。换句话说,它可以更好地防止意外忘记关闭对象:

from urllib.request import urlopen
with urlopen("https://www.example.com") as response:
    response.read(50)
    response.read(50)
b'\n\n\n    
Example D'b'omain\n\n    \n    

urlopen()在此示例中,您从urllib.request模块导入。您使用with关键字 with.urlopen()HTTPResponse对象分配给变量response。然后,您读取响应的前五十个字节,然后读取后面的五十个字节,所有这些都在with块内。最后,您关闭with块,它执行请求并运行其块内的代码行。

使用此代码,您可以显示两组,每组 50 个字节。HTTPResponse一旦退出块范围,该对象将关闭with,这意味着该.read()方法将只返回空字节对象:

import urllib.request
with urllib.request.urlopen("https://www.example.com") as response:
    response.read(50)
b'\n\n\n    Example D'</code></pre> 
   <pre class="kdocs-python"><code class="language-python">response.read(50)</code></pre> 
   <pre class="kdocs-plaintext"><code class="language-plaintext">b''</code></pre> 
   <p style="text-align:left;"><span class="kdocs-fontSize" style="font-size:13pt;">在此示例中,读取五十个字节的第二次调用超出了</span>with<span class="kdocs-fontSize" style="font-size:13pt;">范围。在</span>with<span class="kdocs-fontSize" style="font-size:13pt;">块之外意味着</span>HTTPResponse<span class="kdocs-fontSize" style="font-size:13pt;">关闭,即使您仍然可以访问该变量。如果您尝试从</span>HTTPResponse<span class="kdocs-fontSize" style="font-size:13pt;">它关闭时开始读取,它将返回一个空字节对象。</span></p> 
   <p style="text-align:left;"><span class="kdocs-fontSize" style="font-size:13pt;">另一点需要注意的是,一旦你一直阅读到最后,你就不能重新阅读回复:</span></p> 
   <pre class="kdocs-python"><code class="language-python">import urllib.request
with urllib.request.urlopen("https://www.example.com") as response:
    first_read = response.read()
    second_read = response.read()

len(first_read)</code></pre> 
   <pre class="kdocs-plaintext"><code class="language-plaintext">1256</code></pre> 
   <pre class="kdocs-python"><code class="language-python">len(second_read)</code></pre> 
   <pre class="kdocs-plaintext"><code class="language-plaintext">0</code></pre> 
   <p style="text-align:left;"><span class="kdocs-fontSize" style="font-size:13pt;">这个例子表明,一旦你读过一个回复,你就不能再读了。如果您已完全阅读响应,即使响应未关闭,后续尝试也只会返回一个空字节对象。你必须再次提出请求。</span></p> 
   <p style="text-align:left;"><span class="kdocs-fontSize" style="font-size:13pt;">在这方面,响应与文件对象不同,因为对于文件对象,您可以使用不支持的</span>.seek()<span class="kdocs-fontSize" style="font-size:13pt;">方法多次读取它。</span>HTTPResponse<span class="kdocs-fontSize" style="font-size:13pt;">即使在关闭响应后,您仍然可以访问标头和其他元数据。</span></p> 
   <h4 style="text-align:left;"><span class="kdocs-bold" style="font-weight:bold;">探索文本、八位字节和位</span></h4> 
   <p style="text-align:left;"><span class="kdocs-fontSize" style="font-size:13pt;">到目前为止,在大多数示例中,您从 读取响应主体</span>HTTPResponse<span class="kdocs-fontSize" style="font-size:13pt;">,立即显示结果数据,并注意到它显示为</span><span class="kdocs-fontSize" style="font-size:13pt;">字节对象</span><span class="kdocs-fontSize" style="font-size:13pt;">。这是因为计算机中的文本信息不是以字母形式存储或传输的,而是以字节形式存储和传输的!</span></p> 
   <p style="text-align:left;"><span class="kdocs-fontSize" style="font-size:13pt;">通过网络发送的原始 HTTP 消息被分解为</span><span class="kdocs-fontSize" style="font-size:13pt;">字节</span><span class="kdocs-fontSize" style="font-size:13pt;">序列,有时称为</span><span class="kdocs-fontSize" style="font-size:13pt;">八位字节</span><span class="kdocs-fontSize" style="font-size:13pt;">。字节是 8</span><span class="kdocs-fontSize" style="font-size:13pt;">位</span><span class="kdocs-fontSize" style="font-size:13pt;">块。例如,</span>01010101<span class="kdocs-fontSize" style="font-size:13pt;">是一个字节。要了解有关二进制、位和字节的更多信息,请查看</span><span class="kdocs-fontSize" style="font-size:13pt;">Python 中的位运算符</span><span class="kdocs-fontSize" style="font-size:13pt;">。</span></p> 
   <p style="text-align:left;"><span class="kdocs-fontSize" style="font-size:13pt;">那么如何用字节表示字母呢?一个字节有 256 种可能的组合,您可以为每种组合分配一个字母。您可以分配</span>00000001<span class="kdocs-fontSize" style="font-size:13pt;">给</span>A<span class="kdocs-fontSize" style="font-size:13pt;">、</span>00000010<span class="kdocs-fontSize" style="font-size:13pt;">给</span>B<span class="kdocs-fontSize" style="font-size:13pt;">等等。</span><span class="kdocs-fontSize" style="font-size:13pt;">相当普遍的ASCII</span><span class="kdocs-fontSize" style="font-size:13pt;">字符编码,使用这种系统编码128个字符,对于像英语这样的语言来说已经足够了。这是特别方便的,因为一个字节就可以表示所有的字符,还有空间。</span></p> 
   <p style="text-align:left;"><span class="kdocs-fontSize" style="font-size:13pt;">所有标准英语字符,包括大写字母、标点符号和数字,都适合 ASCII。另一方面,日语被认为有大约五万个符号字符,所以 128 个字符不够用!即使是理论上在一个字节内可用的 256 个字符对于日语来说也远远不够。因此,为了适应世界上所有的语言,有许多不同的字符编码系统。</span></p> 
   <p style="text-align:left;"><span class="kdocs-fontSize" style="font-size:13pt;">尽管有很多系统,但您可以信赖的一件事是它们总是被分解成<span class="kdocs-bold" style="font-weight:bold;">字节</span>。大多数服务器,如果无法解析</span><span class="kdocs-fontSize" style="font-size:13pt;">MIME 类型</span><span class="kdocs-fontSize" style="font-size:13pt;">和字符编码,默认为</span>application/octet-stream<span class="kdocs-fontSize" style="font-size:13pt;">,字面意思是字节流。然后谁收到消息就可以计算出字符编码。</span></p> 
   <h4 style="text-align:left;"><span class="kdocs-bold" style="font-weight:bold;">处理字符编码</span></h4> 
   <p style="text-align:left;"><span class="kdocs-fontSize" style="font-size:13pt;">问题经常出现是因为,正如您可能已经猜到的那样,有很多很多不同的潜在字符编码。当今占主导地位的字符编码是</span><span class="kdocs-fontSize" style="font-size:13pt;">UTF-8</span><span class="kdocs-fontSize" style="font-size:13pt;">,它是</span><span class="kdocs-fontSize" style="font-size:13pt;">Unicode</span><span class="kdocs-fontSize" style="font-size:13pt;">的一种实现。幸运的是,今天</span><span class="kdocs-fontSize" style="font-size:13pt;">98% 的网页</span><span class="kdocs-fontSize" style="font-size:13pt;">都是用 UTF-8 编码的!</span></p> 
   <p style="text-align:left;"><span class="kdocs-fontSize" style="font-size:13pt;">UTF-8 之所以占主导地位,是因为它可以有效地处理数量多得令人难以置信的字符。它处理 Unicode 定义的所有 1,112,064 个潜在字符,包括中文、日文、阿拉伯文(使用从右到左的脚本)、俄文和更多字符集,包括</span><span class="kdocs-fontSize" style="font-size:13pt;">表情符号</span><span class="kdocs-fontSize" style="font-size:13pt;">!</span></p> 
   <p style="text-align:left;"><span class="kdocs-fontSize" style="font-size:13pt;">UTF-8 保持高效,因为它使用可变数量的字节来编码字符,这意味着对于许多字符,它只需要一个字节,而对于其他字符,它可能需要多达四个字节。</span></p> 
   <blockquote class="kdocs-blockquote" style=""> <span class="kdocs-fontSize" style="font-size:13pt;"><span class="kdocs-bold" style="font-weight:bold;">注意</span>:要了解有关 Python 中编码的更多信息,请查看 Python 中的</span> <span class="kdocs-fontSize" style="font-size:13pt;">Unicode 和字符编码:无痛指南</span> <span class="kdocs-fontSize" style="font-size:13pt;">。</span> 
   </blockquote> 
   <p style="text-align:left;"><span class="kdocs-fontSize" style="font-size:13pt;">虽然 UTF-8 占主导地位,并且假设 UTF-8 编码通常不会出错,但您仍然会一直遇到不同的编码。好消息是,在使用</span>urllib.request<span class="kdocs-fontSize" style="font-size:13pt;">.</span></p> 
   <h4 style="text-align:left;"><span class="kdocs-bold" style="font-weight:bold;">从字节到字符串</span></h4> 
   <p style="text-align:left;"><span class="kdocs-fontSize" style="font-size:13pt;">当您使用</span>urllib.request.urlopen()<span class="kdocs-fontSize" style="font-size:13pt;">时,响应的主体是一个字节对象。您可能想要做的第一件事是将字节对象转换为字符串。也许您想做一些</span><span class="kdocs-fontSize" style="font-size:13pt;">网页抓取</span><span class="kdocs-fontSize" style="font-size:13pt;">。为此,您需要<span class="kdocs-bold" style="font-weight:bold;">解码</span>字节。要用 Python 解码字节,您只需找出所使用的<span class="kdocs-bold" style="font-weight:bold;">字符编码</span>即可。编码,特别是指字符编码时,通常称为<span class="kdocs-bold" style="font-weight:bold;">字符集</span>。</span></p> 
   <p style="text-align:left;"><span class="kdocs-fontSize" style="font-size:13pt;">如前所述,在百分之九十八的情况下,默认使用 UTF-8 可能是安全的:</span></p> 
   <pre class="kdocs-python"><code class="language-python">from urllib.request import urlopen
with urlopen("https://www.example.com") as response:
    body = response.read()

decoded_body = body.decode("utf-8")
print(decoded_body[:30])</code></pre> 
   <pre class="kdocs-plaintext"><code class="language-plaintext"><!doctype html>
<html>
<head></code></pre> 
   <p style="text-align:left;"><span class="kdocs-fontSize" style="font-size:13pt;">在此示例中,您获取从返回的字节对象并使用字节对象的方法</span>response.read()<span class="kdocs-fontSize" style="font-size:13pt;">对其进行解码,并将其作为参数传入。当您</span><span class="kdocs-fontSize" style="font-size:13pt;">打印</span><span class="kdocs-fontSize" style="font-size:13pt;">时,您可以看到它现在是一个字符串。</span>.decode()utf-8<span class="kdocs-fontSize" style="font-size:13pt;"> </span>decoded_body</p> 
   <p style="text-align:left;"><span class="kdocs-fontSize" style="font-size:13pt;">也就是说,听之任之很少是一个好的策略。幸运的是,标头是获取字符集信息的好地方:</span></p> 
   <pre class="kdocs-python"><code class="language-python">from urllib.request import urlopen
with urlopen("https://www.example.com") as response:
    body = response.read()

character_set = response.headers.get_content_charset()
character_set</code></pre> 
   <pre class="kdocs-plaintext"><code class="language-plaintext">'utf-8'</code></pre> 
   <pre class="kdocs-python"><code class="language-python">decoded_body = body.decode(character_set)
print(decoded_body[:30])</code></pre> 
   <pre class="kdocs-plaintext"><code class="language-plaintext"><!doctype html>
<html>
<head></code></pre> 
   <p style="text-align:left;"><span class="kdocs-fontSize" style="font-size:13pt;">在此示例中,您调用</span>.get_content_charset()<span class="kdocs-fontSize" style="font-size:13pt;">的</span>.headers<span class="kdocs-fontSize" style="font-size:13pt;">对象</span>response<span class="kdocs-fontSize" style="font-size:13pt;">并使用它进行解码。这是一种解析</span>Content-Type<span class="kdocs-fontSize" style="font-size:13pt;">标头的便捷方法,因此您可以轻松地将字节解码为文本。</span></p> 
   <h4 style="text-align:left;"><span class="kdocs-bold" style="font-weight:bold;">从字节到文件</span></h4> 
   <p style="text-align:left;"><span class="kdocs-fontSize" style="font-size:13pt;">如果您想将字节解码为文本,现在就可以开始了。但是,如果您想将响应的主体写入文件怎么办?那么,你有两个选择:</span></p> 
   <ol start="1"> 
    <li style="margin-left:1.4em;list-style-type:decimal;text-indent:0;text-align:left;"><p><span class="kdocs-fontSize" style="font-size:13pt;">将字节直接写入文件</span></p></li> 
   </ol> 
   <ol start="2"> 
    <li style="margin-left:1.4em;list-style-type:decimal;text-indent:0;text-align:left;"><p><span class="kdocs-fontSize" style="font-size:13pt;">将字节解码为 Python 字符串,然后将字符串编码回文件</span></p></li> 
   </ol> 
   <p style="text-align:left;"><span class="kdocs-fontSize" style="font-size:13pt;">第一种方法最直接,但第二种方法允许您根据需要更改编码。要更详细地了解文件操作,请查看 Real Python 的 Python</span><span class="kdocs-fontSize" style="font-size:13pt;">读写文件(指南)</span><span class="kdocs-fontSize" style="font-size:13pt;">。</span></p> 
   <p style="text-align:left;"><span class="kdocs-fontSize" style="font-size:13pt;">要将字节直接写入文件而无需解码,您需要内置</span>open()<span class="kdocs-fontSize" style="font-size:13pt;">函数,并且需要确保使用写入二进制模式:</span></p> 
   <pre class="kdocs-python"><code class="language-python">from urllib.request import urlopen
with urlopen("https://www.example.com") as response:
    body = response.read()

with open("example.html", mode="wb") as html_file:
    html_file.write(body)</code></pre> 
   <p style="">1256</p> 
   <p style="">使用open()inwb模式绕过解码或编码的需要,并将 HTTP 消息正文的字节转储到example.html文件中。写入操作后输出的数字表示已写入的字节数。就是这样!您已将字节直接写入文件,而无需编码或解码任何内容。</p> 
   <p style="">现在假设您有一个不使用 UTF-8 的 URL,但您希望将内容写入具有 UTF-8 的文件。为此,您首先要将字节解码为字符串,然后将字符串编码为文件,并指定字符编码。</p> 
   <p style="">Google 的主页似乎根据您所在的位置使用不同的编码。在欧洲和美国的大部分地区,它使用ISO-8859-1编码:</p> 
   <pre class="kdocs-python"><code class="language-python">from urllib.request import urlopen
with urlopen("https://www.google.com") as response:
    body = response.read()

character_set = response.headers.get_content_charset()
character_set</code></pre> 
   <p style="">'ISO-8859-1'</p> 
   <pre class="kdocs-python"><code class="language-python">content = body.decode(character_set)
with open("google.html", encoding="utf-8", mode="w") as file:
    file.write(content)</code></pre> 
   <p style="">14066</p> 
   <p style=""><span class="kdocs-fontSize" style="font-size:13pt;">在此代码中,您获得了响应字符集并使用它将字节对象解码为字符串。然后将字符串写入文件,使用 UTF-8 对其进行编码。</span></p> 
   <blockquote class="kdocs-blockquote" style=""> <span class="kdocs-fontSize" style="font-size:13pt;"><span class="kdocs-bold" style="font-weight:bold;">注意</span>:有趣的是,Google 似乎有多层检查,用于确定使用何种语言和编码为网页提供服务。这意味着您可以指定一个</span> Accept-Language <span class="kdocs-fontSize" style="font-size:13pt;">标头</span> <span class="kdocs-fontSize" style="font-size:13pt;">,这似乎会覆盖您的 IP 位置。</span> <span class="kdocs-fontSize" style="font-size:13pt;">用不同的Locale Identifiers</span> <span class="kdocs-fontSize" style="font-size:13pt;">试试,看看你能得到什么编码!</span> 
   </blockquote> 
   <p style="text-align:left;"><span class="kdocs-fontSize" style="font-size:13pt;">写入文件后,您应该能够在浏览器或文本编辑器中打开生成的文件。大多数现代文本处理器都可以自动检测字符编码。</span></p> 
   <p style="text-align:left;"><span class="kdocs-fontSize" style="font-size:13pt;">如果存在编码错误并且您正在使用 Python 读取文件,那么您可能会收到错误消息:</span></p> 
   <pre class="kdocs-python"><code class="language-python">with open("encoding-error.html", mode="r", encoding="utf-8") as file:
    lines = file.readlines()</code></pre> 
   <p style="">UnicodeDecodeError: </p> 
   <p style=""> 'utf-8' codec can't decode byte</p> 
   <p style=""><span class="kdocs-fontSize" style="font-size:13pt;">Python 显式停止进程并引发异常,但在显示文本的程序中,例如您正在查看此页面的浏览器,您可能会发现臭名昭著的</span><span class="kdocs-fontSize" style="font-size:13pt;">替换字符</span><span class="kdocs-fontSize" style="font-size:13pt;">:</span></p> 
   <div class="kdocs-line-container" style="display:flex;"> 
    <div class="kdocs-img" style="flex-direction:column;max-width:100%;display:flex;width:220px;justify-content:center;align-items:center;height:auto;"> 
     <div class="kdocs-img" style="padding-top:100.0%;height:0;"> <a href="http://img.e-com-net.com/image/info8/bdda9a50ecd94391877fffa8a15d5570.jpg" target="_blank"><img src="http://img.e-com-net.com/image/info8/bdda9a50ecd94391877fffa8a15d5570.jpg" style="margin-left:;display:block;width:220px;margin-top:-100.0%;height:auto;;border:1px solid black;" width="220" height="220" alt="【Web Crawler】Python 的 urllib.request 用于 HTTP 请求_第1张图片"></a> 
     </div> 
    </div> 
   </div> 
   <p style="text-indent:1.4em;padding-left:2.8em;">替换字符</p> 
   <p style="text-align:left;"><span class="kdocs-fontSize" style="font-size:13pt;">带有白色问号 (�) 的黑色菱形、正方形 (□) 和矩形 (▯) 通常用作无法解码的字符的替代品。</span></p> 
   <p style="text-align:left;"><span class="kdocs-fontSize" style="font-size:13pt;">有时,解码似乎有效,但会导致无法理解的序列,例如<span class="kdocs-italic" style="font-style:italic;">æ–‡å—化ã '。</span>,这也表明使用了错误的字符集。在日本,他们甚至有一个词来表示由于字符编码问题而出现乱码的文本,</span><span class="kdocs-fontSize" style="font-size:13pt;">Mojibake</span><span class="kdocs-fontSize" style="font-size:13pt;">,因为这些问题在互联网时代开始时就困扰着他们。</span></p> 
   <p style="text-align:left;"><span class="kdocs-fontSize" style="font-size:13pt;">这样,您现在应该能够使用从</span>urlopen()<span class="kdocs-fontSize" style="font-size:13pt;">. 在下一节中,您将学习如何使用该</span>json<span class="kdocs-fontSize" style="font-size:13pt;">模块将字节解析为 Python 字典。</span></p> 
   <h4 style="text-align:left;"><span class="kdocs-bold" style="font-weight:bold;">从字节到字典</span></h4> 
   <p style="">对于application/json响应,您经常会发现它们不包含任何编码信息:</p> 
   <pre class="kdocs-python"><code class="language-python">from urllib.request import urlopen
with urlopen("https://httpbin.org/json") as response:
    body = response.read()

character_set = response.headers.get_content_charset()
print(character_set)</code></pre> 
   <p style="">None</p> 
   <p style="text-align:left;"><span class="kdocs-fontSize" style="font-size:13pt;">在此示例中,您使用</span><span class="kdocs-fontSize" style="font-size:13pt;">httpbin</span>json<span class="kdocs-fontSize" style="font-size:13pt;">的端点,该服务允许您试验不同类型的请求和响应。端点模拟返回 JSON 数据的典型 API。请注意,该方法在其响应中不返回任何内容。</span>json.get_content_charset()</p> 
   <p style="text-align:left;"><span class="kdocs-fontSize" style="font-size:13pt;">即使没有字符编码信息,也不会全部丢失。根据</span><span class="kdocs-fontSize" style="font-size:13pt;">RFC 4627</span><span class="kdocs-fontSize" style="font-size:13pt;">,UTF-8 的默认编码是规范的绝对<span class="kdocs-italic" style="font-style:italic;">要求</span></span>application/json<span class="kdocs-fontSize" style="font-size:13pt;">。这并不是说每个服务器都遵守规则,但一般来说,您可以假设如果传输 JSON,它几乎总是使用 UTF-8 编码。</span></p> 
   <p style="text-align:left;"><span class="kdocs-fontSize" style="font-size:13pt;">幸运的是,</span>json.loads()<span class="kdocs-fontSize" style="font-size:13pt;">在引擎盖下解码字节对象,甚至在它可以处理的不同</span><span class="kdocs-fontSize" style="font-size:13pt;">编码方面有一些回旋余地。</span><span class="kdocs-fontSize" style="font-size:13pt;">因此,</span>json.loads()<span class="kdocs-fontSize" style="font-size:13pt;">只要它们是有效的 JSON,就应该能够处理您抛给它的大多数字节对象:</span></p> 
   <pre class="kdocs-python"><code class="language-python">import json
json.loads(body)</code></pre> 
   <pre class="kdocs-plaintext"><code class="language-plaintext">{'slideshow': {'author': 'Yours Truly', 'date': 'date of publication', 'slides': [{'title': 'Wake up to WonderWidgets!', 'type': 'all'}, {'items': ['Why <em>WonderWidgets</em> are great', 'Who <em>buys</em> WonderWidgets'], 'title': 'Overview', 'type': 'all'}], 'title': 'Sample Slide Show'}}</code></pre> 
   <p style="text-align:left;"><span class="kdocs-fontSize" style="font-size:13pt;">如您所见,该</span>json<span class="kdocs-fontSize" style="font-size:13pt;">模块自动处理解码并生成 Python 字典。几乎所有 API 都以 JSON 形式返回键值信息,尽管您可能会遇到一些使用</span><span class="kdocs-fontSize" style="font-size:13pt;">XML</span><span class="kdocs-fontSize" style="font-size:13pt;">的旧 API 。为此,您可能需要查看</span><span class="kdocs-fontSize" style="font-size:13pt;">Roadmap to XML Parsers in Python</span><span class="kdocs-fontSize" style="font-size:13pt;">。</span></p> 
   <p style="text-align:left;"><span class="kdocs-fontSize" style="font-size:13pt;">有了它,您应该对字节和编码有足够的了解,以免造成危险!在下一节中,您将学习如何排除和修复您在使用</span>urllib.request<span class="kdocs-fontSize" style="font-size:13pt;">.</span></p> 
   <h3 style="text-align:left;"><span class="kdocs-bold" style="font-weight:bold;">常见urllib.request问题</span></h3> 
   <p style="text-align:left;"><span class="kdocs-fontSize" style="font-size:13pt;">无论您是否使用,您都可能在万维网<span class="kdocs-italic" style="font-style:italic;">上</span>遇到多种问题</span>urllib.request<span class="kdocs-fontSize" style="font-size:13pt;">。在本节中,您将学习如何在开始时处理几个最常见的错误:</span><span class="kdocs-bold" style="font-weight:bold;">403</span><span class="kdocs-fontSize" style="font-size:13pt;"><span class="kdocs-bold" style="font-weight:bold;">错误</span>和<span class="kdocs-bold" style="font-weight:bold;">TLS/SSL 证书错误</span>。<span class="kdocs-bold" style="font-weight:bold;">不过,在查看这些特定错误</span>之前,您将首先了解如何在使用</span>urllib.request<span class="kdocs-fontSize" style="font-size:13pt;">.</span></p> 
   <h4 style="text-align:left;"><span class="kdocs-bold" style="font-weight:bold;">实施错误处理</span></h4> 
   <p style="text-align:left;"><span class="kdocs-fontSize" style="font-size:13pt;">在您将注意力转移到特定错误之前,提高您的代码优雅地处理各种错误的能力将会得到回报。Web 开发被错误所困扰,您可以投入大量时间来明智地处理错误。在这里,您将学习在使用</span>urllib.request<span class="kdocs-fontSize" style="font-size:13pt;">.</span></p> 
   <p style="text-align:left;"><span class="kdocs-fontSize" style="font-size:13pt;">HTTP 状态代码</span><span class="kdocs-fontSize" style="font-size:13pt;">伴随着状态行中的每个响应。如果您可以在响应中读取状态代码,则请求已到达其目标。虽然这很好,但如果响应代码以 . 开头,您只能认为请求完全成功</span>2<span class="kdocs-fontSize" style="font-size:13pt;">。例如,</span>200<span class="kdocs-fontSize" style="font-size:13pt;">代表</span>201<span class="kdocs-fontSize" style="font-size:13pt;">成功的请求。如果状态代码是</span>404<span class="kdocs-fontSize" style="font-size:13pt;">或</span>500<span class="kdocs-fontSize" style="font-size:13pt;">,例如,出了点问题,</span>urllib.request<span class="kdocs-fontSize" style="font-size:13pt;">将引发</span>HTTPError<span class="kdocs-fontSize" style="font-size:13pt;">.</span></p> 
   <p style="text-align:left;"><span class="kdocs-fontSize" style="font-size:13pt;">有时会发生错误,提供的 URL 不正确,或者由于其他原因无法建立连接。在这些情况下,</span>urllib.request<span class="kdocs-fontSize" style="font-size:13pt;">将引发</span>URLError<span class="kdocs-fontSize" style="font-size:13pt;">.</span></p> 
   <p style="text-align:left;"><span class="kdocs-fontSize" style="font-size:13pt;">最后,有时服务器就是不响应。也许您的网络连接速度很慢,服务器已关闭,或者服务器被编程为忽略特定请求。为了解决这个问题,您可以在一定时间后将</span>timeout<span class="kdocs-fontSize" style="font-size:13pt;">参数传递</span>urlopen()<span class="kdocs-fontSize" style="font-size:13pt;">给 raise a 。</span>TimeoutError</p> 
   <p style="text-align:left;"><span class="kdocs-fontSize" style="font-size:13pt;">处理这些异常的第一步是捕获它们。您可以使用, , 和classes捕获…块中产生</span>urlopen()<span class="kdocs-fontSize" style="font-size:13pt;">的错误:</span>tryexceptHTTPErrorURLErrorTimeoutError</p> 
   <pre class="kdocs-python"><code class="language-python"># request.py

from urllib.error import HTTPError, URLError
from urllib.request import urlopen

def make_request(url):
    try:
        with urlopen(url, timeout=10) as response:
            print(response.status)
            return response.read(), response
    except HTTPError as error:
        print(error.status, error.reason)
    except URLError as error:
        print(error.reason)
    except TimeoutError:
        print("Request timed out")</code></pre> 
   <p style="text-align:left;"><span class="kdocs-fontSize" style="font-size:13pt;">该函数</span>make_request()<span class="kdocs-fontSize" style="font-size:13pt;">将 URL 字符串作为参数,尝试使用 获取来自该 URL 的响应</span>urllib.request<span class="kdocs-fontSize" style="font-size:13pt;">,并在发生错误时捕获</span>HTTPError<span class="kdocs-fontSize" style="font-size:13pt;">引发的对象。如果 URL 错误,它会捕获一个</span>URLError<span class="kdocs-fontSize" style="font-size:13pt;">. 如果它没有任何错误地通过,它只会打印状态并返回一个包含正文和响应的元组。响应将在 之后关闭</span>return<span class="kdocs-fontSize" style="font-size:13pt;">。</span></p> 
   <p style="text-align:left;"><span class="kdocs-fontSize" style="font-size:13pt;">该函数还调用</span>urlopen()<span class="kdocs-fontSize" style="font-size:13pt;">一个</span>timeout<span class="kdocs-fontSize" style="font-size:13pt;">参数,这将导致</span>TimeoutError<span class="kdocs-fontSize" style="font-size:13pt;">在指定的秒数后引发 a 。十秒通常是等待响应的合适时间,尽管一如既往,这在很大程度上取决于您需要向其发出请求的服务器。</span></p> 
   <p style="text-align:left;"><span class="kdocs-fontSize" style="font-size:13pt;">现在您已准备好优雅地处理各种错误,包括但不限于您接下来将介绍的错误。</span></p> 
   <h4 style="text-align:left;"><span class="kdocs-bold" style="font-weight:bold;">处理403错误</span></h4> 
   <p style="text-align:left;"><span class="kdocs-fontSize" style="font-size:13pt;">您现在将使用该</span>make_request()<span class="kdocs-fontSize" style="font-size:13pt;">函数向</span><span class="kdocs-fontSize" style="font-size:13pt;">httpstat.us</span><span class="kdocs-fontSize" style="font-size:13pt;">发出一些请求,这是一个用于测试的模拟服务器。此模拟服务器将返回具有您请求的状态代码的响应。例如,如果您向 发出请求</span>https://httpstat.us/200<span class="kdocs-fontSize" style="font-size:13pt;">,您应该会得到</span>200<span class="kdocs-fontSize" style="font-size:13pt;">回应。</span></p> 
   <p style="text-align:left;"><span class="kdocs-fontSize" style="font-size:13pt;">像 httpstat.us 这样的 API 用于确保您的应用程序可以处理它可能遇到的所有不同状态代码。httpbin 也有这个功能,但是 httpstat.us 有更全面的状态码选择。它甚至有</span><span class="kdocs-fontSize" style="font-size:13pt;">臭名昭著的半官方</span><span class="kdocs-fontSize" style="font-size:13pt;"> </span>418<span class="kdocs-fontSize" style="font-size:13pt;">状态代码,返回消息<span class="kdocs-italic" style="font-style:italic;">我是茶壶</span>!</span></p> 
   <p style="text-align:left;"><span class="kdocs-fontSize" style="font-size:13pt;">要与</span>make_request()<span class="kdocs-fontSize" style="font-size:13pt;">您在上一节中编写的函数进行交互,请以交互模式运行脚本:</span></p> 
   <pre class="kdocs-shell"><code class="language-shell">$ python3 -i request.py</code></pre> 
   <p style=""><span class="kdocs-fontSize" style="font-size:13pt;">使用</span>-i<span class="kdocs-fontSize" style="font-size:13pt;">标志,此命令将以</span><span class="kdocs-fontSize" style="font-size:13pt;">交互模式</span><span class="kdocs-fontSize" style="font-size:13pt;">运行脚本。这意味着它将执行脚本,然后打开</span><span class="kdocs-fontSize" style="font-size:13pt;">Python REPL</span><span class="kdocs-fontSize" style="font-size:13pt;">,因此您现在可以调用刚刚定义的函数:</span></p> 
   <pre class="kdocs-python"><code class="language-python">>>> make_request("https://httpstat.us/200")
200
(b'200 OK', <http.client.HTTPResponse object at 0x0000023D612660B0>)
>>> make_request("https://httpstat.us/403")
403 Forbidden</code></pre> 
   <p style="text-align:left;"><span class="kdocs-fontSize" style="font-size:13pt;">在这里,您尝试了httpstat.us 的</span>200<span class="kdocs-fontSize" style="font-size:13pt;">和</span>403<span class="kdocs-fontSize" style="font-size:13pt;">端点。</span>200<span class="kdocs-fontSize" style="font-size:13pt;">端点按预期进行并返回响应主体和响应对象。</span>403<span class="kdocs-fontSize" style="font-size:13pt;">端点只是打印了错误消息并且没有返回任何内容,这也符合预期。</span></p> 
   <p style="text-align:left;"><span class="kdocs-fontSize" style="font-size:13pt;">状态意味着服务器理解请求但</span>403<span class="kdocs-fontSize" style="font-size:13pt;">不会满足它。这是您可能会遇到的常见错误,尤其是在网络抓取时。在许多情况下,您可以通过传递</span><span class="kdocs-fontSize" style="font-size:13pt;">User-Agent</span><span class="kdocs-fontSize" style="font-size:13pt;">标头来解决它。</span></p> 
   <blockquote class="kdocs-blockquote" style=""> <span class="kdocs-fontSize" style="font-size:13pt;"><span class="kdocs-bold" style="font-weight:bold;">注意</span>:有两个密切相关的 4xx 代码有时会引起混淆:</span> 
    <br> 401 未经授权 
    <br> 403 禁止 
    <br>401 <span class="kdocs-fontSize" style="font-size:13pt;">如果用户未被识别或登录并且必须执行某些操作以获得访问权限,例如登录或注册,服务器应该返回。</span> 
    <br>403 <span class="kdocs-fontSize" style="font-size:13pt;">如果用户已被充分识别但无权访问资源,则应返回该状态。例如,如果您登录到社交媒体帐户并尝试查看某人的私人资料页面,那么您可能会获得一个</span>403 <span class="kdocs-fontSize" style="font-size:13pt;">状态。</span> 
    <br> <span class="kdocs-fontSize" style="font-size:13pt;">也就是说,不要完全信任状态代码。错误存在并且在复杂的分布式服务中很常见。有些服务器不是模范公民!</span> 
   </blockquote> 
   <p style=""><span class="kdocs-fontSize" style="font-size:13pt;">服务器识别发出请求的人或对象的主要方法之一是检查</span>User-Agent<span class="kdocs-fontSize" style="font-size:13pt;">标头。发送的原始默认请求</span>urllib.request<span class="kdocs-fontSize" style="font-size:13pt;">如下:</span></p> 
   <pre class="kdocs-python"><code class="language-python">GET https://httpstat.us/403 HTTP/1.1
Accept-Encoding: identity
Host: httpstat.us
User-Agent: Python-urllib/3.10
Connection: close</code></pre> 
   <p style=""><span class="kdocs-fontSize" style="font-size:13pt;">请注意,它</span>User-Agent<span class="kdocs-fontSize" style="font-size:13pt;">被列为</span>Python-urllib/3.10<span class="kdocs-fontSize" style="font-size:13pt;">. 您可能会发现某些网站会尝试阻止网络抓取工具,而这</span>User-Agent<span class="kdocs-fontSize" style="font-size:13pt;">是毫无意义的。话虽如此,您可以设置自己的</span>User-Agent<span class="kdocs-fontSize" style="font-size:13pt;">with </span>urllib.request<span class="kdocs-fontSize" style="font-size:13pt;">,但您需要稍微修改一下函数:</span></p> 
   <pre class="kdocs-python"><code class="language-python"> # request.py

 from urllib.error import HTTPError, URLError
-from urllib.request import urlopen
+from urllib.request import urlopen, Request

-def make_request(url):
+def make_request(url, headers=None):
+    request = Request(url, headers=headers or {})
     try:
-        with urlopen(url, timeout=10) as response:
+        with urlopen(request, timeout=10) as response:
             print(response.status)
             return response.read(), response
     except HTTPError as error:
         print(error.status, error.reason)
     except URLError as error:
         print(error.reason)
     except TimeoutError:
         print("Request timed out")</code></pre> 
   <p style=""><span class="kdocs-fontSize" style="font-size:13pt;">要自定义随请求一起发送的标头,您首先必须</span>Request<span class="kdocs-fontSize" style="font-size:13pt;">使用 URL 实例化一个对象。此外,您可以传入</span><span class="kdocs-fontSize" style="font-size:13pt;">关键字参数</span><span class="kdocs-fontSize" style="font-size:13pt;">,</span>headers<span class="kdocs-fontSize" style="font-size:13pt;">它接受代表您希望包含的任何标题的标准字典。因此,不是将 URL 字符串直接传递给 ,而是传递</span>urlopen()<span class="kdocs-fontSize" style="font-size:13pt;">已</span>Request<span class="kdocs-fontSize" style="font-size:13pt;">使用 URL 和标头实例化的对象。</span></p> 
   <blockquote class="kdocs-blockquote" style=""> <span class="kdocs-fontSize" style="font-size:13pt;"><span class="kdocs-bold" style="font-weight:bold;">注意</span>:在上面的示例中,当</span>Request <span class="kdocs-fontSize" style="font-size:13pt;">实例化时,如果已定义标题,则需要将其传递给它。否则,传递一个空白对象,例如</span>{} <span class="kdocs-fontSize" style="font-size:13pt;">. 你不能通过</span>None <span class="kdocs-fontSize" style="font-size:13pt;">,因为这会导致错误。</span> 
   </blockquote> 
   <p style=""><span class="kdocs-fontSize" style="font-size:13pt;">要使用这个改进后的函数,请重新启动交互式会话,然后</span>make_request()<span class="kdocs-fontSize" style="font-size:13pt;">使用表示标头的字典作为参数进行调用:</span></p> 
   <pre class="kdocs-python"><code class="language-python">body, response = make_request(
    "https://www.httpbin.org/user-agent",
    {"User-Agent": "Real Python"}
)</code></pre> 
   <p style="">200</p> 
   <pre class="kdocs-python"><code class="language-python">body</code></pre> 
   <p style="">b'{\n "user-agent": "Real Python"\n}\n'</p> 
   <p style="">在此示例中,您向 httpbin 发出请求。在这里,您使用user-agent端点返回请求的User-Agent值。因为您使用 的自定义用户代理发出了请求Real Python,所以这就是返回的内容。</p> 
   <p style="">但是,有些服务器是严格的,只接受来自特定浏览器的请求。幸运的是,可以User-Agent在网络上找到标准字符串,包括通过用户代理数据库。它们只是字符串,因此您需要做的就是复制要模拟的浏览器的用户代理字符串,并将其用作User-Agent标头的值。</p> 
   <h4 style="text-align:left;"><span class="kdocs-bold" style="font-weight:bold;">修复 SSLCERTIFICATE_VERIFY_FAILED错误</span></h4> 
   <p style="">另一个常见错误是由于 Python 无法访问所需的安全证书。要模拟此错误,您可以使用badssl.com提供的一些具有已知错误 SSL 证书的模拟站点。您可以向其中之一发出请求,例如superfish.badssl.com,并亲身体验该错误:</p> 
   <pre class="kdocs-plaintext"><code class="language-plaintext">from urllib.request import urlopen
urlopen("https://superfish.badssl.com/")</code></pre> 
   <pre class="kdocs-plaintext"><code class="language-plaintext">Traceback (most recent call last):  
  (...)
ssl.SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED]
certificate verify failed: unable to get local issuer certificate (_ssl.c:997)
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
  (...)
urllib.error.URLError: <urlopen error [SSL: CERTIFICATE_VERIFY_FAILED]
certificate verify failed: unable to get local issuer certificate (_ssl.c:997)></code></pre> 
   <p style="text-align:left;"><span class="kdocs-fontSize" style="font-size:13pt;">在这里,向具有已知错误 SSL 证书的地址发出请求将</span>CERTIFICATE_VERIFY_FAILED<span class="kdocs-fontSize" style="font-size:13pt;">导致</span>URLError<span class="kdocs-fontSize" style="font-size:13pt;">.</span></p> 
   <p style="text-align:left;"><span class="kdocs-fontSize" style="font-size:13pt;">SSL 代表安全套接字层。这是用词不当,因为 SSL 已被弃用,取而代之的是 TLS,即</span><span class="kdocs-fontSize" style="font-size:13pt;">传输层安全</span><span class="kdocs-fontSize" style="font-size:13pt;">性。有时旧术语只是坚持!这是一种加密网络流量的方法,这样假设的侦听器就无法窃听通过线路传输的信息。</span></p> 
   <p style="text-align:left;"><span class="kdocs-fontSize" style="font-size:13pt;">现在,大多数网站地址的前面不是,</span>http://<span class="kdocs-fontSize" style="font-size:13pt;">而是<span class="kdocs-italic" style="font-style:italic;">s</span>代表<span class="kdocs-italic" style="font-style:italic;">安全</span>。</span><span class="kdocs-fontSize" style="font-size:13pt;">HTTPS</span><span class="kdocs-fontSize" style="font-size:13pt;">连接必须通过 TLS 加密。可以处理 HTTP 和 HTTPS 连接。</span>https://urllib.request</p> 
   <p style="text-align:left;"><span class="kdocs-fontSize" style="font-size:13pt;">HTTPS 的详细信息远远超出了本教程的范围,但您可以将 HTTPS 连接视为涉及两个阶段,即</span><span class="kdocs-fontSize" style="font-size:13pt;">握手</span><span class="kdocs-fontSize" style="font-size:13pt;">和信息传输。握手确保连接安全。有关 Python 和 HTTPS 的更多信息,请查看</span><span class="kdocs-fontSize" style="font-size:13pt;">使用 Python 探索 HTTPS</span><span class="kdocs-fontSize" style="font-size:13pt;">。</span></p> 
   <p style="text-align:left;"><span class="kdocs-fontSize" style="font-size:13pt;">为了确定特定服务器是安全的,发出请求的程序依赖于可信证书的存储。服务器的证书在握手阶段进行验证。Python 使用</span><span class="kdocs-fontSize" style="font-size:13pt;">操作系统的证书存储</span><span class="kdocs-fontSize" style="font-size:13pt;">。如果 Python 找不到系统的证书存储,或者存储已过期,那么您将遇到此错误。</span></p> 
   <blockquote class="kdocs-blockquote" style=""> <span class="kdocs-fontSize" style="font-size:13pt;"><span class="kdocs-bold" style="font-weight:bold;">注意</span>:在以前的 Python 版本中,默认行为</span>urllib.request <span class="kdocs-fontSize" style="font-size:13pt;">是<span class="kdocs-bold" style="font-weight:bold;">不</span>验证证书,这导致</span> <span class="kdocs-fontSize" style="font-size:13pt;">PEP 476</span> <span class="kdocs-fontSize" style="font-size:13pt;">默认启用证书验证。</span> <span class="kdocs-fontSize" style="font-size:13pt;">默认值在Python 3.4.3</span> <span class="kdocs-fontSize" style="font-size:13pt;">中更改。</span> 
   </blockquote> 
   <p style="text-align:left;"><span class="kdocs-fontSize" style="font-size:13pt;">有时 Python 可以访问的证书存储已过时,或者 Python 无法访问它,无论出于何种原因。这是令人沮丧的,因为有时您可以从浏览器访问该 URL,它认为它是安全的,但</span>urllib.request<span class="kdocs-fontSize" style="font-size:13pt;">仍然会引发此错误。</span></p> 
   <p style="text-align:left;"><span class="kdocs-fontSize" style="font-size:13pt;">您可能想选择不验证证书,但这会使您的连接<span class="kdocs-italic" style="font-style:italic;">不安全</span>,绝对<span class="kdocs-italic" style="font-style:italic;">不推荐</span>:</span></p> 
   <pre class="kdocs-python"><code class="language-python">import ssl
from urllib.request import urlopen
unverified_context = ssl._create_unverified_context()
urlopen("https://superfish.badssl.com/", context=unverified_context)</code></pre> 
   <pre class="kdocs-plaintext"><code class="language-plaintext"><http.client.HTTPResponse object at 0x00000209CBE8F220></code></pre> 
   <p style="text-align:left;"><span class="kdocs-fontSize" style="font-size:13pt;">在这里您导入</span>ssl<span class="kdocs-fontSize" style="font-size:13pt;">模块,它允许您创建一个</span><span class="kdocs-fontSize" style="font-size:13pt;">未验证的上下文</span><span class="kdocs-fontSize" style="font-size:13pt;">。然后,您可以将此上下文传递给</span>urlopen()<span class="kdocs-fontSize" style="font-size:13pt;">并访问已知的错误 SSL 证书。连接成功通过,因为未检查 SSL 证书。</span></p> 
   <p style="text-align:left;"><span class="kdocs-fontSize" style="font-size:13pt;">在诉诸这些孤注一掷的措施之前,请尝试更新您的操作系统或更新您的 Python 版本。如果失败,那么您可以从</span>requests<span class="kdocs-fontSize" style="font-size:13pt;">库中获取一个页面并安装</span>certifi<span class="kdocs-fontSize" style="font-size:13pt;">:</span></p> 
   <pre class="kdocs-shell"><code class="language-shell">$ python3 -m venv venv
$ source venv/bin/activate.sh
(venv) $ python3 -m pip install certifi</code></pre> 
   <p style="">certifi<span class="kdocs-fontSize" style="font-size:13pt;">是一个证书集合,您可以使用它来代替系统的集合。</span>certifi<span class="kdocs-fontSize" style="font-size:13pt;">您可以通过使用证书捆绑而不是操作系统的捆绑创建 SSL 上下文来执行此操作:</span></p> 
   <pre class="kdocs-python"><code class="language-python">import ssl
from urllib.request import urlopen
import certifi
certifi_context = ssl.create_default_context(cafile=certifi.where())
urlopen("https://sha384.badssl.com/", context=certifi_context)</code></pre> 
   <pre class="kdocs-plaintext"><code class="language-plaintext"><http.client.HTTPResponse object at 0x000001C7407C3490></code></pre> 
   <p style="text-align:left;"><span class="kdocs-fontSize" style="font-size:13pt;">在此示例中,您曾经</span>certifi<span class="kdocs-fontSize" style="font-size:13pt;">充当 SSL 证书存储,并使用它成功连接到具有已知良好 SSL 证书的站点。请注意</span>._create_unverified_context()<span class="kdocs-fontSize" style="font-size:13pt;">,您使用的不是</span>.create_default_context()<span class="kdocs-fontSize" style="font-size:13pt;">。</span></p> 
   <p style="text-align:left;"><span class="kdocs-fontSize" style="font-size:13pt;">这样,您就可以保持安全而不会遇到太多麻烦!在下一节中,您将涉足身份验证的世界。</span></p> 
   <h3 style="text-align:left;"><span class="kdocs-bold" style="font-weight:bold;">经过身份验证的请求</span></h3> 
   <p style="text-align:left;">requests<span class="kdocs-fontSize" style="font-size:13pt;">身份验证是一个庞大的主题,如果您要处理的身份验证比此处介绍的内容复杂得多,那么这可能是进入该包的一个很好的起点。</span></p> 
   <p style="text-align:left;"><span class="kdocs-fontSize" style="font-size:13pt;">在本教程中,您将只介绍一种身份验证方法,它作为您必须进行的调整类型的示例来验证您的请求。</span>urllib.request<span class="kdocs-fontSize" style="font-size:13pt;">确实有很多其他功能可以帮助进行身份验证,但本教程不会介绍这些功能。</span></p> 
   <p style="text-align:left;"><span class="kdocs-fontSize" style="font-size:13pt;">最常见的身份验证工具之一是不记名令牌,由</span><span class="kdocs-fontSize" style="font-size:13pt;">RFC 6750</span><span class="kdocs-fontSize" style="font-size:13pt;">指定。它通常用作</span><span class="kdocs-fontSize" style="font-size:13pt;">OAuth</span><span class="kdocs-fontSize" style="font-size:13pt;">的一部分,但也可以单独使用。它也是最常见的标题,您可以将其与当前</span>make_request()<span class="kdocs-fontSize" style="font-size:13pt;">函数一起使用:</span></p> 
   <pre class="kdocs-python"><code class="language-python">token = "abcdefghijklmnopqrstuvwxyz"
headers = {
    "Authorization": f"Bearer {token}"
}
make_request("https://httpbin.org/bearer", headers)</code></pre> 
   <pre class="kdocs-plaintext"><code class="language-plaintext">200
(b'{\n  "authenticated": true, \n  "token": "abcdefghijklmnopqrstuvwxyz"\n}\n',
<http.client.HTTPResponse object at 0x0000023D612642E0>)</code></pre> 
   <p style="text-align:left;">/bearer<span class="kdocs-fontSize" style="font-size:13pt;">在此示例中,您向模拟承载身份验证的 httpbin 端点发出请求。它会接受任何字符串作为标记。它只需要 RFC 6750 指定的正确格式。名称<span class="kdocs-italic" style="font-style:italic;">必须</span>是</span>Authorization<span class="kdocs-fontSize" style="font-size:13pt;">,有时是小写字母</span>authorization<span class="kdocs-fontSize" style="font-size:13pt;">,值<span class="kdocs-italic" style="font-style:italic;">必须</span>是</span>Bearer<span class="kdocs-fontSize" style="font-size:13pt;">,在它和标记之间有一个空格。</span></p> 
   <blockquote class="kdocs-blockquote" style=""> <span class="kdocs-fontSize" style="font-size:13pt;"><span class="kdocs-bold" style="font-weight:bold;">注意</span>:如果您使用任何形式的令牌或秘密信息,请务必妥善保护这些令牌。例如,不要将它们提交到 GitHub 存储库,而是将它们存储为临时</span> <span class="kdocs-fontSize" style="font-size:13pt;">环境变量</span> <span class="kdocs-fontSize" style="font-size:13pt;">。</span> 
   </blockquote> 
   <p style="text-align:left;"><span class="kdocs-fontSize" style="font-size:13pt;">恭喜,您已使用不记名令牌成功通过身份验证!</span></p> 
   <p style="text-align:left;"><span class="kdocs-fontSize" style="font-size:13pt;">另一种身份验证形式称为</span><span class="kdocs-fontSize" style="font-size:13pt;"><span class="kdocs-bold" style="font-weight:bold;">基本访问身份验证</span></span><span class="kdocs-fontSize" style="font-size:13pt;">,这是一种非常简单的身份验证方法,只比在标头中发送用户名和密码好一点。很没有安全感!</span></p> 
   <p style="text-align:left;"><span class="kdocs-fontSize" style="font-size:13pt;">当今最常用的协议之一是</span><span class="kdocs-fontSize" style="font-size:13pt;"><span class="kdocs-bold" style="font-weight:bold;">OAuth(开放授权)</span></span><span class="kdocs-fontSize" style="font-size:13pt;">。如果您曾使用 Google、GitHub 或 Facebook 登录其他网站,那么您就使用过 OAuth。OAuth 流程通常涉及您要与之交互的服务和身份服务器之间的一些请求,从而产生一个短暂的不记名令牌。该持有者令牌随后可用于持有者身份验证一段时间。</span></p> 
   <p style="text-align:left;"><span class="kdocs-fontSize" style="font-size:13pt;">大部分身份验证归结为了解目标服务器使用的特定协议并仔细阅读文档以使其正常工作。</span></p> 
   <h3 style="text-align:left;"><span class="kdocs-bold" style="font-weight:bold;">POST 请求urllib.request</span></h3> 
   <p style="text-align:left;"><span class="kdocs-fontSize" style="font-size:13pt;">您发出了很多 GET 请求,但有时您想要<span class="kdocs-italic" style="font-style:italic;">发送</span>信息。这就是 POST 请求的用武之地。要使用 发出 POST 请求</span>urllib.request<span class="kdocs-fontSize" style="font-size:13pt;">,您不必显式更改方法。您可以只将</span>data<span class="kdocs-fontSize" style="font-size:13pt;">对象传递给新</span>Request<span class="kdocs-fontSize" style="font-size:13pt;">对象或直接传递给</span>urlopen()<span class="kdocs-fontSize" style="font-size:13pt;">. 但是,该</span>data<span class="kdocs-fontSize" style="font-size:13pt;">对象必须采用特殊格式。您将</span>make_request()<span class="kdocs-fontSize" style="font-size:13pt;">通过添加参数稍微调整您的函数以支持 POST 请求</span>data<span class="kdocs-fontSize" style="font-size:13pt;">:</span></p> 
   <pre class="kdocs-python"><code class="language-python"># request.py

from urllib.error import HTTPError, URLError
from urllib.request import urlopen, Request

-def make_request(url, headers=None):
+def make_request(url, headers=None, data=None):

-    request = Request(url, headers=headers or {})
+    request = Request(url, headers=headers or {}, data=data)
     try:
         with urlopen(request, timeout=10) as response:
             print(response.status)
             return response.read(), response
     except HTTPError as error:
         print(error.status, error.reason)
     except URLError as error:
         print(error.reason)
     except TimeoutError:
         print("Request timed out")</code></pre> 
   <p style="text-align:left;"><span class="kdocs-fontSize" style="font-size:13pt;">在这里,您只是修改了函数以接受</span>data<span class="kdocs-fontSize" style="font-size:13pt;">默认值为 的参数</span>None<span class="kdocs-fontSize" style="font-size:13pt;">,并将其直接传递到</span>Request<span class="kdocs-fontSize" style="font-size:13pt;">实例化中。不过,这还不是全部。您可以使用两种不同格式中的一种来执行 POST 请求:</span></p> 
   <ol start="1"> 
    <li style="margin-left:1.4em;list-style-type:decimal;text-indent:0;"><p><span class="kdocs-bold" style="font-weight:bold;">表格数据</span>:application/x-www-form-urlencoded</p></li> 
   </ol> 
   <ol start="2"> 
    <li style="margin-left:1.4em;list-style-type:decimal;text-indent:0;"><p><span class="kdocs-bold" style="font-weight:bold;">JSON</span>:application/json</p></li> 
   </ol> 
   <p style="text-align:left;"><span class="kdocs-fontSize" style="font-size:13pt;">第一种格式是最古老的 POST 请求格式,涉及使用</span><span class="kdocs-fontSize" style="font-size:13pt;">百分比编码</span><span class="kdocs-fontSize" style="font-size:13pt;">对数据进行编码,也称为 URL 编码。</span><span class="kdocs-fontSize" style="font-size:13pt;">您可能已经注意到编码为查询字符串</span><span class="kdocs-fontSize" style="font-size:13pt;">的键值对 URL 。键与值用等号 ( </span>=<span class="kdocs-fontSize" style="font-size:13pt;">) 分隔,键值对用 & 符号 ( </span>&<span class="kdocs-fontSize" style="font-size:13pt;">) 分隔,空格通常被抑制但可以用加号 ( </span>+<span class="kdocs-fontSize" style="font-size:13pt;">) 代替。</span></p> 
   <p style="text-align:left;"><span class="kdocs-fontSize" style="font-size:13pt;">如果您从 Python 字典开始,要在您的</span>make_request()<span class="kdocs-fontSize" style="font-size:13pt;">函数中使用表单数据格式,您需要编码两次:</span></p> 
   <ol start="3"> 
    <li style="margin-left:1.4em;list-style-type:decimal;text-indent:0;"><p>一次对字典进行 URL 编码</p></li> 
   </ol> 
   <ol start="4"> 
    <li style="margin-left:1.4em;list-style-type:decimal;text-indent:0;"><p>然后再次将结果字符串编码为字节</p></li> 
   </ol> 
   <p style="text-align:left;"><span class="kdocs-fontSize" style="font-size:13pt;">对于 URL 编码的第一阶段,您将使用另一个</span>urllib<span class="kdocs-fontSize" style="font-size:13pt;">模块</span>urllib.parse<span class="kdocs-fontSize" style="font-size:13pt;">. 请记住以交互模式启动您的脚本,以便您可以使用该</span>make_request()<span class="kdocs-fontSize" style="font-size:13pt;">函数并在 REPL 上运行它:</span></p> 
   <pre class="kdocs-python"><code class="language-python">from urllib.parse import urlencode
post_dict = {"Title": "Hello World", "Name": "Real Python"}
url_encoded_data = urlencode(post_dict)
url_encoded_data
# 'Title=Hello+World&Name=Real+Python'
post_data = url_encoded_data.encode("utf-8")
body, response = make_request(
    "https://httpbin.org/anything", data=post_data
)
# 200
print(body.decode("utf-8"))</code></pre> 
   <pre class="kdocs-plaintext"><code class="language-plaintext">{
  "args": {},
  "data": "",
  "files": {},
  "form": {
    "Name": "Real Python",
    "Title": "Hello World"  },
  "headers": {
    "Accept-Encoding": "identity",
    "Content-Length": "34",
    "Content-Type": "application/x-www-form-urlencoded",
    "Host": "httpbin.org",
    "User-Agent": "Python-urllib/3.10",
    "X-Amzn-Trace-Id": "Root=1-61f25a81-03d2d4377f0abae95ff34096"  },
  "json": null,
  "method": "POST",
  "origin": "86.159.145.119",
  "url": "https://httpbin.org/anything"}</code></pre> 
   <p style="text-align:left;"><span class="kdocs-fontSize" style="font-size:13pt;">在这个例子中,你:</span></p> 
   <ol start="5"> 
    <li style="margin-left:1.4em;list-style-type:decimal;text-indent:0;"><p>urlencode()从urllib.parse模块导入</p></li> 
   </ol> 
   <ol start="6"> 
    <li style="margin-left:1.4em;list-style-type:decimal;text-indent:0;"><p>初始化您的 POST 数据,从字典开始</p></li> 
   </ol> 
   <ol start="7"> 
    <li style="margin-left:1.4em;list-style-type:decimal;text-indent:0;"><p>使用urlencode()函数对字典进行编码</p></li> 
   </ol> 
   <ol start="8"> 
    <li style="margin-left:1.4em;list-style-type:decimal;text-indent:0;"><p>使用 UTF-8 编码将生成的字符串编码为字节</p></li> 
   </ol> 
   <ol start="9"> 
    <li style="margin-left:1.4em;list-style-type:decimal;text-indent:0;"><p>向anything端点发出请求httpbin.org</p></li> 
   </ol> 
   <ol start="10"> 
    <li style="margin-left:1.4em;list-style-type:decimal;text-indent:0;"><p>打印 UTF-8 解码的响应正文</p></li> 
   </ol> 
   <p style="text-align:left;"><span class="kdocs-fontSize" style="font-size:13pt;">UTF-8 编码是类型</span><span class="kdocs-fontSize" style="font-size:13pt;">规范</span><span class="kdocs-fontSize" style="font-size:13pt;">的一部分</span>application/x-www-form-urlencoded<span class="kdocs-fontSize" style="font-size:13pt;">。UTF-8 被抢先用于解码正文,因为您已经知道</span>httpbin.org<span class="kdocs-fontSize" style="font-size:13pt;">可靠地使用 UTF-8。</span></p> 
   <p style="text-align:left;"><span class="kdocs-fontSize" style="font-size:13pt;">来自 httpbin的</span>anything<span class="kdocs-fontSize" style="font-size:13pt;">端点充当一种回显,返回它收到的所有信息,以便您可以检查您发出的请求的详细信息。在这种情况下,您可以确认</span>method<span class="kdocs-fontSize" style="font-size:13pt;">确实是</span>POST<span class="kdocs-fontSize" style="font-size:13pt;">,并且可以看到您发送的数据列在 下</span>form<span class="kdocs-fontSize" style="font-size:13pt;">。</span></p> 
   <p style="text-align:left;"><span class="kdocs-fontSize" style="font-size:13pt;">要使用 JSON 发出相同的请求,您将使用 将 Python 字典转换为 JSON 字符串</span>json.dumps()<span class="kdocs-fontSize" style="font-size:13pt;">,使用 UTF-8 对其进行编码,将其作为</span>data<span class="kdocs-fontSize" style="font-size:13pt;">参数传递,最后添加一个特殊的标头以指示数据类型为 JSON:</span></p> 
   <pre class="kdocs-python"><code class="language-python">post_dict = {"Title": "Hello World", "Name": "Real Python"}
import json
json_string = json.dumps(post_dict)
json_string</code></pre> 
   <p style="">'{"Title": "Hello World", "Name": "Real Python"}'</p> 
   <pre class="kdocs-python"><code class="language-python">post_data = json_string.encode("utf-8")
body, response = make_request(
   "https://httpbin.org/anything",
    data=post_data,
    headers={"Content-Type": "application/json"},
)</code></pre> 
   <p style="">200</p> 
   <pre class="kdocs-python"><code class="language-python">print(body.decode("utf-8"))</code></pre> 
   <pre class="kdocs-plaintext"><code class="language-plaintext">{
  "args": {},
  "data": "{\"Title\": \"Hello World\", \"Name\": \"Real Python\"}",
  "files": {},
  "form": {},
  "headers": {
    "Accept-Encoding": "identity",
    "Content-Length": "47",
    "Content-Type": "application/json",
    "Host": "httpbin.org",
    "User-Agent": "Python-urllib/3.10",
    "X-Amzn-Trace-Id": "Root=1-61f25a81-3e35d1c219c6b5944e2d8a52"
  },
  "json": {
    "Name": "Real Python",
    "Title": "Hello World"
  },
  "method": "POST",
  "origin": "86.159.145.119",
  "url": "https://httpbin.org/anything"
}</code></pre> 
   <p style="">这次要序列化json.dumps()字典,您使用而不是urlencode(). 您还明确添加了Content-Type值为application/json. 有了这些信息,httpbin 服务器就可以在接收端反序列化 JSON。在其响应中,您可以看到json键下列出的数据。</p> 
   <blockquote class="kdocs-blockquote" style=""> <span class="kdocs-bold" style="font-weight:bold;">注意</span>:有时需要将 JSON 数据作为纯文本发送,在这种情况下,步骤与上述相同,只是您设置Content-Type为text/plain; charset=UTF-8. 许多这些必需品取决于您将数据发送到的服务器或 API,因此请务必阅读文档并进行实验! 
   </blockquote> 
   <p style="">这样,您现在就可以开始发出 POST 请求了。本教程不会详细介绍其他请求方法,例如PUT。可以这么说,您还可以通过将method关键字参数传递给Request对象的实例化来显式设置方法。</p> 
   <h3 style="text-align:left;"><span class="kdocs-bold" style="font-weight:bold;">请求包生态系统</span></h3> 
   <p style="text-align:left;"><span class="kdocs-fontSize" style="font-size:13pt;">最后,本教程的最后一部分致力于阐明围绕使用 Python 的 HTTP 请求的包生态系统。因为包很多,没有明确的标准,容易造成混淆。也就是说,每个包都有用例,这就意味着你有更多的选择!</span></p> 
   <h4 style="text-align:left;"><span class="kdocs-bold" style="font-weight:bold;">urllib2和是什么urllib3?</span></h4> 
   <p style="text-align:left;"><span class="kdocs-fontSize" style="font-size:13pt;">要回答这个问题,你需要回到早期的 Python,一路回到 1.2 版本,也就是最初</span>urllib<span class="kdocs-fontSize" style="font-size:13pt;">引入的时候。在 1.6 版左右,</span>urllib2<span class="kdocs-fontSize" style="font-size:13pt;">添加了一个修改版,它与原来的</span>urllib<span class="kdocs-fontSize" style="font-size:13pt;">. 当 Python 3 出现时,原来的</span>urllib<span class="kdocs-fontSize" style="font-size:13pt;">版本被弃用,并</span>urllib2<span class="kdocs-fontSize" style="font-size:13pt;">删除了</span>2<span class="kdocs-fontSize" style="font-size:13pt;">, 并采用了原来的</span>urllib<span class="kdocs-fontSize" style="font-size:13pt;">名称。它也分为几个部分:</span></p> 
   <ul> 
    <li style="margin-left:1.4em;list-style-type:disc;text-indent:0;text-align:left;"><p>urllib.error</p></li> 
   </ul> 
   <ul> 
    <li style="margin-left:1.4em;list-style-type:disc;text-indent:0;text-align:left;"><p>urllib.parse</p></li> 
   </ul> 
   <ul> 
    <li style="margin-left:1.4em;list-style-type:disc;text-indent:0;text-align:left;"><p>urllib.request</p></li> 
   </ul> 
   <ul> 
    <li style="margin-left:1.4em;list-style-type:disc;text-indent:0;text-align:left;"><p>urllib.response</p></li> 
   </ul> 
   <ul> 
    <li style="margin-left:1.4em;list-style-type:disc;text-indent:0;text-align:left;"><p>urllib.robotparser</p></li> 
   </ul> 
   <p style="text-align:left;"><span class="kdocs-fontSize" style="font-size:13pt;">那么呢</span>urllib3<span class="kdocs-fontSize" style="font-size:13pt;">?</span>urllib2<span class="kdocs-fontSize" style="font-size:13pt;">那是仍然存在时开发的第三方库。它与标准库无关,因为它是一个独立维护的库。有趣的是,</span>requests<span class="kdocs-fontSize" style="font-size:13pt;">图书馆实际上</span>urllib3<span class="kdocs-fontSize" style="font-size:13pt;">在幕后使用,所以</span>pip<span class="kdocs-fontSize" style="font-size:13pt;">!</span></p> 
   <h4 style="text-align:left;"><span class="kdocs-bold" style="font-weight:bold;">我应该什么时候使用requestsOver urllib.request?</span></h4> 
   <p style="text-align:left;"><span class="kdocs-fontSize" style="font-size:13pt;">主要的答案是易用性和安全性。</span>urllib.request<span class="kdocs-fontSize" style="font-size:13pt;">被认为是一个低级库,它公开了很多关于 HTTP 请求工作的细节。的Python</span><span class="kdocs-fontSize" style="font-size:13pt;">文档</span>urllib.request<span class="kdocs-fontSize" style="font-size:13pt;">毫不含糊地推荐</span>requests<span class="kdocs-fontSize" style="font-size:13pt;">作为更高级别的 HTTP 客户端接口。</span></p> 
   <p style="text-align:left;"><span class="kdocs-fontSize" style="font-size:13pt;">如果您日复一日地与许多不同的 REST API 进行交互,那么</span>requests<span class="kdocs-fontSize" style="font-size:13pt;">强烈建议您使用。该</span>requests<span class="kdocs-fontSize" style="font-size:13pt;">库标榜自己为“为人类而建”,并成功地围绕 HTTP 创建了一个直观、安全和直接的 API。它通常被认为是首选图书馆!如果您想了解有关该</span>requests<span class="kdocs-fontSize" style="font-size:13pt;">库的更多信息,请查看 Real Python</span><span class="kdocs-fontSize" style="font-size:13pt;">指南</span>requests<span class="kdocs-fontSize" style="font-size:13pt;">。</span></p> 
   <p style="text-align:left;">requests<span class="kdocs-fontSize" style="font-size:13pt;">如何让事情变得更简单的一个例子是字符编码。您会记得,使用 时</span>urllib.request<span class="kdocs-fontSize" style="font-size:13pt;">,您必须了解编码并采取一些步骤来确保无差错的体验。该</span>requests<span class="kdocs-fontSize" style="font-size:13pt;">包将其抽象化,并将通过使用</span>chardet<span class="kdocs-fontSize" style="font-size:13pt;">通用字符编码检测器来解析编码,以防万一有任何有趣的事情。</span></p> 
   <p style="text-align:left;"><span class="kdocs-fontSize" style="font-size:13pt;">如果您的目标是了解有关标准 Python 的更多信息以及它如何处理 HTTP 请求的详细信息,那么这</span>urllib.request<span class="kdocs-fontSize" style="font-size:13pt;">是进入该领域的好方法。您甚至可以走得更远,使用非常低级的</span>http<span class="kdocs-fontSize" style="font-size:13pt;">模块</span><span class="kdocs-fontSize" style="font-size:13pt;">。另一方面,您可能只想将依赖性保持在最低限度,这</span>urllib.request<span class="kdocs-fontSize" style="font-size:13pt;">是完全可以做到的。</span></p> 
   <h4 style="text-align:left;"><span class="kdocs-bold" style="font-weight:bold;">为什么requests不是标准库的一部分?</span></h4> 
   <p style="text-align:left;"><span class="kdocs-fontSize" style="font-size:13pt;">也许您想知道为什么</span>requests<span class="kdocs-fontSize" style="font-size:13pt;">此时它还不是核心 Python 的一部分。</span></p> 
   <p style="text-align:left;"><span class="kdocs-fontSize" style="font-size:13pt;">这是一个复杂的问题,没有硬性的快速答案。关于原因有很多猜测,但似乎有两个原因很突出:</span></p> 
   <ol start="1"> 
    <li style="margin-left:1.4em;list-style-type:decimal;text-indent:0;text-align:left;"><p>requests<span class="kdocs-fontSize" style="font-size:13pt;">还有其他需要集成的第三方依赖项。</span></p></li> 
   </ol> 
   <ol start="2"> 
    <li style="margin-left:1.4em;list-style-type:decimal;text-indent:0;text-align:left;"><p>requests<span class="kdocs-fontSize" style="font-size:13pt;">需要保持敏捷并且可以在标准库之外做得更好。</span></p></li> 
   </ol> 
   <p style="text-align:left;"><span class="kdocs-fontSize" style="font-size:13pt;">该</span>requests<span class="kdocs-fontSize" style="font-size:13pt;">库具有第三方依赖项。集成</span>requests<span class="kdocs-fontSize" style="font-size:13pt;">到标准库中还意味着集成</span>chardet<span class="kdocs-fontSize" style="font-size:13pt;">、</span>certifi<span class="kdocs-fontSize" style="font-size:13pt;">、 和</span>urllib3<span class="kdocs-fontSize" style="font-size:13pt;">等。另一种方法是从根本上改变</span>requests<span class="kdocs-fontSize" style="font-size:13pt;">为仅使用 Python 现有的标准库。这不是一项简单的任务!</span></p> 
   <p style="text-align:left;"><span class="kdocs-fontSize" style="font-size:13pt;">集成</span>requests<span class="kdocs-fontSize" style="font-size:13pt;">还意味着开发该库的现有团队将不得不放弃对设计和实施的完全控制,让位于</span><span class="kdocs-fontSize" style="font-size:13pt;">PEP</span><span class="kdocs-fontSize" style="font-size:13pt;">决策过程。</span></p> 
   <p style="text-align:left;"><span class="kdocs-fontSize" style="font-size:13pt;">HTTP 规范和建议一直在变化,高级库必须足够敏捷才能跟上。如果有一个安全漏洞需要修补,或者有一个新的工作流程需要添加,</span>requests<span class="kdocs-fontSize" style="font-size:13pt;">团队可以比他们作为 Python 发布过程的一部分更快地构建和发布。据推测,有时他们会在发现漏洞后十二小时发布安全修复程序!</span></p> 
   <p style="text-align:left;"><span class="kdocs-fontSize" style="font-size:13pt;">有关这些问题和更多问题的有趣概述,请查看</span><span class="kdocs-fontSize" style="font-size:13pt;">将请求添加到标准库</span><span class="kdocs-fontSize" style="font-size:13pt;">,它总结了在 Python 语言峰会上与Requests 的创建者和维护者</span><span class="kdocs-fontSize" style="font-size:13pt;">Kenneth Reitz的讨论。</span></p> 
   <p style="text-align:left;">requests<span class="kdocs-fontSize" style="font-size:13pt;">因为这种敏捷性对于它及其底层是如此必要,所以经常使用对于标准库来说太重要</span>urllib3<span class="kdocs-fontSize" style="font-size:13pt;">的自相矛盾的陈述。</span>requests<span class="kdocs-fontSize" style="font-size:13pt;">这是因为 Python 社区的大部分依赖</span>requests<span class="kdocs-fontSize" style="font-size:13pt;">及其敏捷性,将其集成到核心 Python 中可能会损害它和 Python 社区。</span></p> 
   <p style="text-align:left;"><span class="kdocs-fontSize" style="font-size:13pt;">在 GitHub 存储库问题板上</span>requests<span class="kdocs-fontSize" style="font-size:13pt;">,发布了一个问题,要求将 包含</span>requests<span class="kdocs-fontSize" style="font-size:13pt;">在标准库</span><span class="kdocs-fontSize" style="font-size:13pt;">中。和的开发人员</span>requests<span class="kdocs-fontSize" style="font-size:13pt;">插话</span>urllib3<span class="kdocs-fontSize" style="font-size:13pt;">,主要是说他们可能会对自己维护它失去兴趣。有些人甚至表示他们会分叉存储库并继续为他们自己的用例开发它们。</span></p> 
   <p style="text-align:left;"><span class="kdocs-fontSize" style="font-size:13pt;">话虽如此,请注意</span>requests<span class="kdocs-fontSize" style="font-size:13pt;">库 GitHub 存储库托管在 Python 软件基金会的帐户下。仅仅因为某些东西不是 Python 标准库的一部分并不意味着它不是生态系统不可或缺的一部分!</span></p> 
   <p style="text-align:left;"><span class="kdocs-fontSize" style="font-size:13pt;">目前的情况似乎对 Python 核心团队和</span>requests<span class="kdocs-fontSize" style="font-size:13pt;">. 虽然对于新手来说可能有点混乱,但现有结构为 HTTP 请求提供了最稳定的体验。</span></p> 
   <p style="text-align:left;"><span class="kdocs-fontSize" style="font-size:13pt;">同样重要的是要注意 HTTP 请求本质上是复杂的。</span>urllib.request<span class="kdocs-fontSize" style="font-size:13pt;">不要试图粉饰太多。它公开了 HTTP 请求的许多内部工作原理,这就是为什么它被标榜为低级模块的原因。您的选择实际上取决于您的特定用例、安全问题和偏好</span>requests<span class="kdocs-fontSize" style="font-size:13pt;">。</span>urllib.request</p> 
   <h3 style="text-align:left;"><span class="kdocs-bold" style="font-weight:bold;">结论</span></h3> 
   <p style="text-align:left;"><span class="kdocs-fontSize" style="font-size:13pt;">您现在已准备好使用它</span>urllib.request<span class="kdocs-fontSize" style="font-size:13pt;">来发出 HTTP 请求。现在您可以在您的项目中使用这个内置模块,让它们更长时间地保持无依赖性。您还通过使用较低级别的模块(例如</span>urllib.request<span class="kdocs-fontSize" style="font-size:13pt;">.</span></p> 
   <p style="text-align:left;"><span class="kdocs-fontSize" style="font-size:13pt;"><span class="kdocs-bold" style="font-weight:bold;">在本教程中,您已经:</span></span></p> 
   <ul> 
    <li style="margin-left:1.4em;list-style-type:disc;text-indent:0;"><p>学习了如何发出基本的<span class="kdocs-bold" style="font-weight:bold;">HTTP 请求</span>urllib.request</p></li> 
   </ul> 
   <ul> 
    <li style="margin-left:1.4em;list-style-type:disc;text-indent:0;"><p>探究了<span class="kdocs-bold" style="font-weight:bold;">HTTP 消息</span>的具体细节并研究了它是如何由urllib.request</p></li> 
   </ul> 
   <ul> 
    <li style="margin-left:1.4em;list-style-type:disc;text-indent:0;"><p>弄清楚如何处理HTTP 消息的字符<span class="kdocs-bold" style="font-weight:bold;">编码</span></p></li> 
   </ul> 
   <ul> 
    <li style="margin-left:1.4em;list-style-type:disc;text-indent:0;"><p>探索了一些使用中<span class="kdocs-bold" style="font-weight:bold;">的常见错误</span>,urllib.request并学习了如何解决这些错误</p></li> 
   </ul> 
   <ul> 
    <li style="margin-left:1.4em;list-style-type:disc;text-indent:0;"><p>将您的脚趾浸入经过<span class="kdocs-bold" style="font-weight:bold;">身份验证的请求</span>的世界urllib.request</p></li> 
   </ul> 
   <ul> 
    <li style="margin-left:1.4em;list-style-type:disc;text-indent:0;"><p>理解为什么两者urllib和requests库都存在以及<span class="kdocs-bold" style="font-weight:bold;">何时使用其中一个或另一个</span></p></li> 
   </ul> 
   <p style="text-align:left;"><span class="kdocs-fontSize" style="font-size:13pt;">您现在可以使用 发出基本的 HTTP 请求</span>urllib.request<span class="kdocs-fontSize" style="font-size:13pt;">,并且您还拥有使用标准库深入研究低级 HTTP 领域的工具。最后,您可以根据自己的需要选择是否使用</span>requests<span class="kdocs-fontSize" style="font-size:13pt;">或。</span>urllib.request<span class="kdocs-fontSize" style="font-size:13pt;">享受探索网络的乐趣!</span></p> 
  </div> 
 </div> 
</div>
                            </div>
                        </div>
                    </div>
                    <!--PC和WAP自适应版-->
                    <div id="SOHUCS" sid="1735423176713756672"></div>
                    <script type="text/javascript" src="/views/front/js/chanyan.js"></script>
                    <!-- 文章页-底部 动态广告位 -->
                    <div class="youdao-fixed-ad" id="detail_ad_bottom"></div>
                </div>
                <div class="col-md-3">
                    <div class="row" id="ad">
                        <!-- 文章页-右侧1 动态广告位 -->
                        <div id="right-1" class="col-lg-12 col-md-12 col-sm-4 col-xs-4 ad">
                            <div class="youdao-fixed-ad" id="detail_ad_1"> </div>
                        </div>
                        <!-- 文章页-右侧2 动态广告位 -->
                        <div id="right-2" class="col-lg-12 col-md-12 col-sm-4 col-xs-4 ad">
                            <div class="youdao-fixed-ad" id="detail_ad_2"></div>
                        </div>
                        <!-- 文章页-右侧3 动态广告位 -->
                        <div id="right-3" class="col-lg-12 col-md-12 col-sm-4 col-xs-4 ad">
                            <div class="youdao-fixed-ad" id="detail_ad_3"></div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
    <div class="container">
        <h4 class="pt20 mb15 mt0 border-top">你可能感兴趣的:(网络爬虫(Web,Crawler),python,http,开发语言)</h4>
        <div id="paradigm-article-related">
            <div class="recommend-post mb30">
                <ul class="widget-links">
                    <li><a href="/article/1835511912843014144.htm"
                           title="理解Gunicorn:Python WSGI服务器的基石" target="_blank">理解Gunicorn:Python WSGI服务器的基石</a>
                        <span class="text-muted">范范0825</span>
<a class="tag" taget="_blank" href="/search/ipython/1.htm">ipython</a><a class="tag" taget="_blank" href="/search/linux/1.htm">linux</a><a class="tag" taget="_blank" href="/search/%E8%BF%90%E7%BB%B4/1.htm">运维</a>
                        <div>理解Gunicorn:PythonWSGI服务器的基石介绍Gunicorn,全称GreenUnicorn,是一个为PythonWSGI(WebServerGatewayInterface)应用设计的高效、轻量级HTTP服务器。作为PythonWeb应用部署的常用工具,Gunicorn以其高性能和易用性著称。本文将介绍Gunicorn的基本概念、安装和配置,帮助初学者快速上手。1.什么是Gunico</div>
                    </li>
                    <li><a href="/article/1835509770287673344.htm"
                           title="swagger访问路径" target="_blank">swagger访问路径</a>
                        <span class="text-muted">igotyback</span>
<a class="tag" taget="_blank" href="/search/swagger/1.htm">swagger</a>
                        <div>Swagger2.x版本访问地址:http://{ip}:{port}/{context-path}/swagger-ui.html{ip}是你的服务器IP地址。{port}是你的应用服务端口,通常为8080。{context-path}是你的应用上下文路径,如果应用部署在根路径下,则为空。Swagger3.x版本对于Swagger3.x版本(也称为OpenAPI3)访问地址:http://{ip</div>
                    </li>
                    <li><a href="/article/1835506869838376960.htm"
                           title="Python数据分析与可视化实战指南" target="_blank">Python数据分析与可视化实战指南</a>
                        <span class="text-muted">William数据分析</span>
<a class="tag" taget="_blank" href="/search/python/1.htm">python</a><a class="tag" taget="_blank" href="/search/python/1.htm">python</a><a class="tag" taget="_blank" href="/search/%E6%95%B0%E6%8D%AE/1.htm">数据</a>
                        <div>在数据驱动的时代,Python因其简洁的语法、强大的库生态系统以及活跃的社区,成为了数据分析与可视化的首选语言。本文将通过一个详细的案例,带领大家学习如何使用Python进行数据分析,并通过可视化来直观呈现分析结果。一、环境准备1.1安装必要库在开始数据分析和可视化之前,我们需要安装一些常用的库。主要包括pandas、numpy、matplotlib和seaborn等。这些库分别用于数据处理、数学</div>
                    </li>
                    <li><a href="/article/1835505858939809792.htm"
                           title="python os.environ" target="_blank">python os.environ</a>
                        <span class="text-muted">江湖偌大</span>
<a class="tag" taget="_blank" href="/search/python/1.htm">python</a><a class="tag" taget="_blank" href="/search/%E6%B7%B1%E5%BA%A6%E5%AD%A6%E4%B9%A0/1.htm">深度学习</a>
                        <div>os.environ['TF_CPP_MIN_LOG_LEVEL']='0'#默认值,输出所有信息os.environ['TF_CPP_MIN_LOG_LEVEL']='1'#屏蔽通知信息(INFO)os.environ['TF_CPP_MIN_LOG_LEVEL']='2'#屏蔽通知信息和警告信息(INFO\WARNING)os.environ['TF_CPP_MIN_LOG_LEVEL']='</div>
                    </li>
                    <li><a href="/article/1835505606245576704.htm"
                           title="Python中os.environ基本介绍及使用方法" target="_blank">Python中os.environ基本介绍及使用方法</a>
                        <span class="text-muted">鹤冲天Pro</span>
<a class="tag" taget="_blank" href="/search/%23/1.htm">#</a><a class="tag" taget="_blank" href="/search/Python/1.htm">Python</a><a class="tag" taget="_blank" href="/search/python/1.htm">python</a><a class="tag" taget="_blank" href="/search/%E6%9C%8D%E5%8A%A1%E5%99%A8/1.htm">服务器</a><a class="tag" taget="_blank" href="/search/%E5%BC%80%E5%8F%91%E8%AF%AD%E8%A8%80/1.htm">开发语言</a>
                        <div>文章目录python中os.environos.environ简介os.environ进行环境变量的增删改查python中os.environ的使用详解1.简介2.key字段详解2.1常见key字段3.os.environ.get()用法4.环境变量的增删改查和判断是否存在4.1新增环境变量4.2更新环境变量4.3获取环境变量4.4删除环境变量4.5判断环境变量是否存在python中os.envi</div>
                    </li>
                    <li><a href="/article/1835505226933694464.htm"
                           title="Pyecharts数据可视化大屏:打造沉浸式数据分析体验" target="_blank">Pyecharts数据可视化大屏:打造沉浸式数据分析体验</a>
                        <span class="text-muted">我的运维人生</span>
<a class="tag" taget="_blank" href="/search/%E4%BF%A1%E6%81%AF%E5%8F%AF%E8%A7%86%E5%8C%96/1.htm">信息可视化</a><a class="tag" taget="_blank" href="/search/%E6%95%B0%E6%8D%AE%E5%88%86%E6%9E%90/1.htm">数据分析</a><a class="tag" taget="_blank" href="/search/%E6%95%B0%E6%8D%AE%E6%8C%96%E6%8E%98/1.htm">数据挖掘</a><a class="tag" taget="_blank" href="/search/%E8%BF%90%E7%BB%B4%E5%BC%80%E5%8F%91/1.htm">运维开发</a><a class="tag" taget="_blank" href="/search/%E6%8A%80%E6%9C%AF%E5%85%B1%E4%BA%AB/1.htm">技术共享</a>
                        <div>Pyecharts数据可视化大屏:打造沉浸式数据分析体验在当今这个数据驱动的时代,如何将海量数据以直观、生动的方式展现出来,成为了数据分析师和企业决策者关注的焦点。Pyecharts,作为一款基于Python的开源数据可视化库,凭借其丰富的图表类型、灵活的配置选项以及高度的定制化能力,成为了构建数据可视化大屏的理想选择。本文将深入探讨如何利用Pyecharts打造数据可视化大屏,并通过实际代码案例</div>
                    </li>
                    <li><a href="/article/1835504217729626112.htm"
                           title="Python教程:一文了解使用Python处理XPath" target="_blank">Python教程:一文了解使用Python处理XPath</a>
                        <span class="text-muted">旦莫</span>
<a class="tag" taget="_blank" href="/search/Python%E8%BF%9B%E9%98%B6/1.htm">Python进阶</a><a class="tag" taget="_blank" href="/search/python/1.htm">python</a><a class="tag" taget="_blank" href="/search/%E5%BC%80%E5%8F%91%E8%AF%AD%E8%A8%80/1.htm">开发语言</a>
                        <div>目录1.环境准备1.1安装lxml1.2验证安装2.XPath基础2.1什么是XPath?2.2XPath语法2.3示例XML文档3.使用lxml解析XML3.1解析XML文档3.2查看解析结果4.XPath查询4.1基本路径查询4.2使用属性查询4.3查询多个节点5.XPath的高级用法5.1使用逻辑运算符5.2使用函数6.实战案例6.1从网页抓取数据6.1.1安装Requests库6.1.2代</div>
                    </li>
                    <li><a href="/article/1835504218178416640.htm"
                           title="Google earth studio 简介" target="_blank">Google earth studio 简介</a>
                        <span class="text-muted">陟彼高冈yu</span>
<a class="tag" taget="_blank" href="/search/%E6%97%85%E6%B8%B8/1.htm">旅游</a>
                        <div>GoogleEarthStudio是一个基于Web的动画工具,专为创作使用GoogleEarth数据的动画和视频而设计。它利用了GoogleEarth强大的三维地图和卫星影像数据库,使用户能够轻松地创建逼真的地球动画、航拍视频和动态地图可视化。网址为https://www.google.com/earth/studio/。GoogleEarthStudio是一个基于Web的动画工具,专为创作使用G</div>
                    </li>
                    <li><a href="/article/1835503965563875328.htm"
                           title="python os.environ_python os.environ 读取和设置环境变量" target="_blank">python os.environ_python os.environ 读取和设置环境变量</a>
                        <span class="text-muted">weixin_39605414</span>
<a class="tag" taget="_blank" href="/search/python/1.htm">python</a><a class="tag" taget="_blank" href="/search/os.environ/1.htm">os.environ</a>
                        <div>>>>importos>>>os.environ.keys()['LC_NUMERIC','GOPATH','GOROOT','GOBIN','LESSOPEN','SSH_CLIENT','LOGNAME','USER','HOME','LC_PAPER','PATH','DISPLAY','LANG','TERM','SHELL','J2REDIR','LC_MONETARY','QT_QPA</div>
                    </li>
                    <li><a href="/article/1835502578050363392.htm"
                           title="PHP环境搭建详细教程" target="_blank">PHP环境搭建详细教程</a>
                        <span class="text-muted">好看资源平台</span>
<a class="tag" taget="_blank" href="/search/%E5%89%8D%E7%AB%AF/1.htm">前端</a><a class="tag" taget="_blank" href="/search/php/1.htm">php</a>
                        <div>PHP是一个流行的服务器端脚本语言,广泛用于Web开发。为了使PHP能够在本地或服务器上运行,我们需要搭建一个合适的PHP环境。本教程将结合最新资料,介绍在不同操作系统上搭建PHP开发环境的多种方法,包括Windows、macOS和Linux系统的安装步骤,以及本地和Docker环境的配置。1.PHP环境搭建概述PHP环境的搭建主要分为以下几类:集成开发环境:例如XAMPP、WAMP、MAMP,这</div>
                    </li>
                    <li><a href="/article/1835499615491813376.htm"
                           title="四章-32-点要素的聚合" target="_blank">四章-32-点要素的聚合</a>
                        <span class="text-muted">彩云飘过</span>

                        <div>本文基于腾讯课堂老胡的课《跟我学Openlayers--基础实例详解》做的学习笔记,使用的openlayers5.3.xapi。源码见1032.html,对应的官网示例https://openlayers.org/en/latest/examples/cluster.htmlhttps://openlayers.org/en/latest/examples/earthquake-clusters.</div>
                    </li>
                    <li><a href="/article/1835499052125483008.htm"
                           title="Git常用命令-修改远程仓库地址" target="_blank">Git常用命令-修改远程仓库地址</a>
                        <span class="text-muted">猿大师</span>
<a class="tag" taget="_blank" href="/search/Linux/1.htm">Linux</a><a class="tag" taget="_blank" href="/search/Java/1.htm">Java</a><a class="tag" taget="_blank" href="/search/git/1.htm">git</a><a class="tag" taget="_blank" href="/search/java/1.htm">java</a>
                        <div>查看远程仓库地址gitremote-v返回结果originhttps://git.coding.net/*****.git(fetch)originhttps://git.coding.net/*****.git(push)修改远程仓库地址gitremoteset-urloriginhttps://git.coding.net/*****.git先删除后增加远程仓库地址gitremotermori</div>
                    </li>
                    <li><a href="/article/1835498925755297792.htm"
                           title="DIV+CSS+JavaScript技术制作网页(旅游主题网页设计与制作)云南大理" target="_blank">DIV+CSS+JavaScript技术制作网页(旅游主题网页设计与制作)云南大理</a>
                        <span class="text-muted">STU学生网页设计</span>
<a class="tag" taget="_blank" href="/search/%E7%BD%91%E9%A1%B5%E8%AE%BE%E8%AE%A1/1.htm">网页设计</a><a class="tag" taget="_blank" href="/search/%E6%9C%9F%E6%9C%AB%E7%BD%91%E9%A1%B5%E4%BD%9C%E4%B8%9A/1.htm">期末网页作业</a><a class="tag" taget="_blank" href="/search/html%E9%9D%99%E6%80%81%E7%BD%91%E9%A1%B5/1.htm">html静态网页</a><a class="tag" taget="_blank" href="/search/html5%E6%9C%9F%E6%9C%AB%E5%A4%A7%E4%BD%9C%E4%B8%9A/1.htm">html5期末大作业</a><a class="tag" taget="_blank" href="/search/%E7%BD%91%E9%A1%B5%E8%AE%BE%E8%AE%A1/1.htm">网页设计</a><a class="tag" taget="_blank" href="/search/web%E5%A4%A7%E4%BD%9C%E4%B8%9A/1.htm">web大作业</a>
                        <div>️精彩专栏推荐作者主页:【进入主页—获取更多源码】web前端期末大作业:【HTML5网页期末作业(1000套)】程序员有趣的告白方式:【HTML七夕情人节表白网页制作(110套)】文章目录二、网站介绍三、网站效果▶️1.视频演示2.图片演示四、网站代码HTML结构代码CSS样式代码五、更多源码二、网站介绍网站布局方面:计划采用目前主流的、能兼容各大主流浏览器、显示效果稳定的浮动网页布局结构。网站程</div>
                    </li>
                    <li><a href="/article/1835497664922349568.htm"
                           title="使用Faiss进行高效相似度搜索" target="_blank">使用Faiss进行高效相似度搜索</a>
                        <span class="text-muted">llzwxh888</span>
<a class="tag" taget="_blank" href="/search/faiss/1.htm">faiss</a><a class="tag" taget="_blank" href="/search/python/1.htm">python</a>
                        <div>在现代AI应用中,快速和高效的相似度搜索是至关重要的。Faiss(FacebookAISimilaritySearch)是一个专门用于快速相似度搜索和聚类的库,特别适用于高维向量。本文将介绍如何使用Faiss来进行相似度搜索,并结合Python代码演示其基本用法。什么是Faiss?Faiss是一个由FacebookAIResearch团队开发的开源库,主要用于高维向量的相似性搜索和聚类。Faiss</div>
                    </li>
                    <li><a href="/article/1835497665853485056.htm"
                           title="python是什么意思中文-在python中%是什么意思" target="_blank">python是什么意思中文-在python中%是什么意思</a>
                        <span class="text-muted">编程大乐趣</span>

                        <div>Python中%有两种:1、数值运算:%代表取模,返回除法的余数。如:>>>7%212、%操作符(字符串格式化,stringformatting),说明如下:%[(name)][flags][width].[precision]typecode(name)为命名flags可以有+,-,''或0。+表示右对齐。-表示左对齐。''为一个空格,表示在正数的左侧填充一个空格,从而与负数对齐。0表示使用0填</div>
                    </li>
                    <li><a href="/article/1835497537369370624.htm"
                           title="利用Requests Toolkit轻松完成HTTP请求" target="_blank">利用Requests Toolkit轻松完成HTTP请求</a>
                        <span class="text-muted">nseejrukjhad</span>
<a class="tag" taget="_blank" href="/search/http/1.htm">http</a><a class="tag" taget="_blank" href="/search/%E7%BD%91%E7%BB%9C%E5%8D%8F%E8%AE%AE/1.htm">网络协议</a><a class="tag" taget="_blank" href="/search/%E7%BD%91%E7%BB%9C/1.htm">网络</a><a class="tag" taget="_blank" href="/search/python/1.htm">python</a>
                        <div>RequestsToolkit的力量:轻松构建HTTP请求Agent在现代软件开发中,API请求是与外部服务交互的核心。RequestsToolkit提供了一种便捷的方式,帮助开发者构建自动化的HTTP请求Agent。本文旨在详细介绍RequestsToolkit的设置、使用和潜在挑战。引言RequestsToolkit是一个强大的工具包,可用于构建执行HTTP请求的智能代理。这对于想要自动化与外</div>
                    </li>
                    <li><a href="/article/1835496402042580992.htm"
                           title="GitHub上克隆项目" target="_blank">GitHub上克隆项目</a>
                        <span class="text-muted">bigbig猩猩</span>
<a class="tag" taget="_blank" href="/search/github/1.htm">github</a>
                        <div>从GitHub上克隆项目是一个简单且直接的过程,它允许你将远程仓库中的项目复制到你的本地计算机上,以便进行进一步的开发、测试或学习。以下是一个详细的步骤指南,帮助你从GitHub上克隆项目。一、准备工作1.安装Git在克隆GitHub项目之前,你需要在你的计算机上安装Git工具。Git是一个开源的分布式版本控制系统,用于跟踪和管理代码变更。你可以从Git的官方网站(https://git-scm.</div>
                    </li>
                    <li><a href="/article/1835496149843275776.htm"
                           title="关于城市旅游的HTML网页设计——(旅游风景云南 5页)HTML+CSS+JavaScript" target="_blank">关于城市旅游的HTML网页设计——(旅游风景云南 5页)HTML+CSS+JavaScript</a>
                        <span class="text-muted">二挡起步</span>
<a class="tag" taget="_blank" href="/search/web%E5%89%8D%E7%AB%AF%E6%9C%9F%E6%9C%AB%E5%A4%A7%E4%BD%9C%E4%B8%9A/1.htm">web前端期末大作业</a><a class="tag" taget="_blank" href="/search/javascript/1.htm">javascript</a><a class="tag" taget="_blank" href="/search/html/1.htm">html</a><a class="tag" taget="_blank" href="/search/css/1.htm">css</a><a class="tag" taget="_blank" href="/search/%E6%97%85%E6%B8%B8/1.htm">旅游</a><a class="tag" taget="_blank" href="/search/%E9%A3%8E%E6%99%AF/1.htm">风景</a>
                        <div>⛵源码获取文末联系✈Web前端开发技术描述网页设计题材,DIV+CSS布局制作,HTML+CSS网页设计期末课程大作业|游景点介绍|旅游风景区|家乡介绍|等网站的设计与制作|HTML期末大学生网页设计作业,Web大学生网页HTML:结构CSS:样式在操作方面上运用了html5和css3,采用了div+css结构、表单、超链接、浮动、绝对定位、相对定位、字体样式、引用视频等基础知识JavaScrip</div>
                    </li>
                    <li><a href="/article/1835496148601761792.htm"
                           title="HTML网页设计制作大作业(div+css) 云南我的家乡旅游景点 带文字滚动" target="_blank">HTML网页设计制作大作业(div+css) 云南我的家乡旅游景点 带文字滚动</a>
                        <span class="text-muted">二挡起步</span>
<a class="tag" taget="_blank" href="/search/web%E5%89%8D%E7%AB%AF%E6%9C%9F%E6%9C%AB%E5%A4%A7%E4%BD%9C%E4%B8%9A/1.htm">web前端期末大作业</a><a class="tag" taget="_blank" href="/search/web%E8%AE%BE%E8%AE%A1%E7%BD%91%E9%A1%B5%E8%A7%84%E5%88%92%E4%B8%8E%E8%AE%BE%E8%AE%A1/1.htm">web设计网页规划与设计</a><a class="tag" taget="_blank" href="/search/html/1.htm">html</a><a class="tag" taget="_blank" href="/search/css/1.htm">css</a><a class="tag" taget="_blank" href="/search/javascript/1.htm">javascript</a><a class="tag" taget="_blank" href="/search/dreamweaver/1.htm">dreamweaver</a><a class="tag" taget="_blank" href="/search/%E5%89%8D%E7%AB%AF/1.htm">前端</a>
                        <div>Web前端开发技术描述网页设计题材,DIV+CSS布局制作,HTML+CSS网页设计期末课程大作业游景点介绍|旅游风景区|家乡介绍|等网站的设计与制作HTML期末大学生网页设计作业HTML:结构CSS:样式在操作方面上运用了html5和css3,采用了div+css结构、表单、超链接、浮动、绝对定位、相对定位、字体样式、引用视频等基础知识JavaScript:做与用户的交互行为文章目录前端学习路线</div>
                    </li>
                    <li><a href="/article/1835495644123459584.htm"
                           title="Day1笔记-Python简介&标识符和关键字&输入输出" target="_blank">Day1笔记-Python简介&标识符和关键字&输入输出</a>
                        <span class="text-muted">~在杰难逃~</span>
<a class="tag" taget="_blank" href="/search/Python/1.htm">Python</a><a class="tag" taget="_blank" href="/search/python/1.htm">python</a><a class="tag" taget="_blank" href="/search/%E5%BC%80%E5%8F%91%E8%AF%AD%E8%A8%80/1.htm">开发语言</a><a class="tag" taget="_blank" href="/search/%E5%A4%A7%E6%95%B0%E6%8D%AE/1.htm">大数据</a><a class="tag" taget="_blank" href="/search/%E6%95%B0%E6%8D%AE%E5%88%86%E6%9E%90/1.htm">数据分析</a><a class="tag" taget="_blank" href="/search/%E6%95%B0%E6%8D%AE%E6%8C%96%E6%8E%98/1.htm">数据挖掘</a>
                        <div>大家好,从今天开始呢,杰哥开展一个新的专栏,当然,数据分析部分也会不定时更新的,这个新的专栏主要是讲解一些Python的基础语法和知识,帮助0基础的小伙伴入门和学习Python,感兴趣的小伙伴可以开始认真学习啦!一、Python简介【了解】1.计算机工作原理编程语言就是用来定义计算机程序的形式语言。我们通过编程语言来编写程序代码,再通过语言处理程序执行向计算机发送指令,让计算机完成对应的工作,编程</div>
                    </li>
                    <li><a href="/article/1835495517774245888.htm"
                           title="python八股文面试题分享及解析(1)" target="_blank">python八股文面试题分享及解析(1)</a>
                        <span class="text-muted">Shawn________</span>
<a class="tag" taget="_blank" href="/search/python/1.htm">python</a>
                        <div>#1.'''a=1b=2不用中间变量交换a和b'''#1.a=1b=2a,b=b,aprint(a)print(b)结果:21#2.ll=[]foriinrange(3):ll.append({'num':i})print(11)结果:#[{'num':0},{'num':1},{'num':2}]#3.kk=[]a={'num':0}foriinrange(3):#0,12#可变类型,不仅仅改变</div>
                    </li>
                    <li><a href="/article/1835495170972413952.htm"
                           title="git - Webhook让部署自动化" target="_blank">git - Webhook让部署自动化</a>
                        <span class="text-muted">大猪大猪</span>

                        <div>我们现在有一个需求,将项目打包上传到gitlab或者github后,程序能自动部署,不用手动地去服务器中进行项目更新并运行,如何做到?这里我们可以使用gitlab与github的挂钩,挂钩的原理就是,每当我们有请求到gitlab与github服务器时,这时他俩会根据我们配置的挂钩地扯进行访问,webhook挂钩程序会一直监听着某个端口请求,一但收到他们发过来的请求,这时就知道用户有请求提交了,这时</div>
                    </li>
                    <li><a href="/article/1835493753557708800.htm"
                           title="每日算法&面试题,大厂特训二十八天——第二十天(树)" target="_blank">每日算法&面试题,大厂特训二十八天——第二十天(树)</a>
                        <span class="text-muted">肥学</span>
<a class="tag" taget="_blank" href="/search/%E2%9A%A1%E7%AE%97%E6%B3%95%E9%A2%98%E2%9A%A1%E9%9D%A2%E8%AF%95%E9%A2%98%E6%AF%8F%E6%97%A5%E7%B2%BE%E8%BF%9B/1.htm">⚡算法题⚡面试题每日精进</a><a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/%E7%AE%97%E6%B3%95/1.htm">算法</a><a class="tag" taget="_blank" href="/search/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84/1.htm">数据结构</a>
                        <div>目录标题导读算法特训二十八天面试题点击直接资料领取导读肥友们为了更好的去帮助新同学适应算法和面试题,最近我们开始进行专项突击一步一步来。上一期我们完成了动态规划二十一天现在我们进行下一项对各类算法进行二十八天的一个小总结。还在等什么快来一起肥学进行二十八天挑战吧!!特别介绍小白练手专栏,适合刚入手的新人欢迎订阅编程小白进阶python有趣练手项目里面包括了像《机器人尬聊》《恶搞程序》这样的有趣文章</div>
                    </li>
                    <li><a href="/article/1835493626688401408.htm"
                           title="Python快速入门 —— 第三节:类与对象" target="_blank">Python快速入门 —— 第三节:类与对象</a>
                        <span class="text-muted">孤华暗香</span>
<a class="tag" taget="_blank" href="/search/Python%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8/1.htm">Python快速入门</a><a class="tag" taget="_blank" href="/search/python/1.htm">python</a><a class="tag" taget="_blank" href="/search/%E5%BC%80%E5%8F%91%E8%AF%AD%E8%A8%80/1.htm">开发语言</a>
                        <div>第三节:类与对象目标:了解面向对象编程的基础概念,并学会如何定义类和创建对象。内容:类与对象:定义类:class关键字。类的构造函数:__init__()。类的属性和方法。对象的创建与使用。示例:classStudent:def__init__(self,name,age,major):self.name&#</div>
                    </li>
                    <li><a href="/article/1835493373906087936.htm"
                           title="libyuv之linux编译" target="_blank">libyuv之linux编译</a>
                        <span class="text-muted">jaronho</span>
<a class="tag" taget="_blank" href="/search/Linux/1.htm">Linux</a><a class="tag" taget="_blank" href="/search/linux/1.htm">linux</a><a class="tag" taget="_blank" href="/search/%E8%BF%90%E7%BB%B4/1.htm">运维</a><a class="tag" taget="_blank" href="/search/%E6%9C%8D%E5%8A%A1%E5%99%A8/1.htm">服务器</a>
                        <div>文章目录一、下载源码二、编译源码三、注意事项1、银河麒麟系统(aarch64)(1)解决armv8-a+dotprod+i8mm指令集支持问题(2)解决armv9-a+sve2指令集支持问题一、下载源码到GitHub网站下载https://github.com/lemenkov/libyuv源码,或者用直接用git克隆到本地,如:gitclonehttps://github.com/lemenko</div>
                    </li>
                    <li><a href="/article/1835493267907637248.htm"
                           title="webpack图片等资源的处理" target="_blank">webpack图片等资源的处理</a>
                        <span class="text-muted">dmengmeng</span>

                        <div>需要的loaderfile-loader(让我们可以引入这些资源文件)url-loader(其实是file-loader的二次封装)img-loader(处理图片所需要的)在没有使用任何处理图片的loader之前,比如说css中用到了背景图片,那么最后打包会报错的,因为他没办法处理图片。其实你只想能够使用图片的话。只加一个file-loader就可以,打开网页能准确看到图片。{test:/\.(p</div>
                    </li>
                    <li><a href="/article/1835493247179386880.htm"
                           title="Faiss Tips:高效向量搜索与聚类的利器" target="_blank">Faiss Tips:高效向量搜索与聚类的利器</a>
                        <span class="text-muted">焦习娜Samantha</span>

                        <div>FaissTips:高效向量搜索与聚类的利器faiss_tipsSomeusefultipsforfaiss项目地址:https://gitcode.com/gh_mirrors/fa/faiss_tips项目介绍Faiss是由FacebookAIResearch开发的一个用于高效相似性搜索和密集向量聚类的库。它支持多种硬件平台,包括CPU和GPU,能够在海量数据集上实现快速的近似最近邻搜索(AN</div>
                    </li>
                    <li><a href="/article/1835492869062881280.htm"
                           title="pyecharts——绘制柱形图折线图" target="_blank">pyecharts——绘制柱形图折线图</a>
                        <span class="text-muted">2224070247</span>
<a class="tag" taget="_blank" href="/search/%E4%BF%A1%E6%81%AF%E5%8F%AF%E8%A7%86%E5%8C%96/1.htm">信息可视化</a><a class="tag" taget="_blank" href="/search/python/1.htm">python</a><a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/%E6%95%B0%E6%8D%AE%E5%8F%AF%E8%A7%86%E5%8C%96/1.htm">数据可视化</a>
                        <div>一、pyecharts概述自2013年6月百度EFE(ExcellentFrontEnd)数据可视化团队研发的ECharts1.0发布到GitHub网站以来,ECharts一直备受业界权威的关注并获得广泛好评,成为目前成熟且流行的数据可视化图表工具,被应用到诸多数据可视化的开发领域。Python作为数据分析领域最受欢迎的语言,也加入ECharts的使用行列,并研发出方便Python开发者使用的数据</div>
                    </li>
                    <li><a href="/article/1835491859351302144.htm"
                           title="Python 实现图片裁剪(附代码) | Python工具" target="_blank">Python 实现图片裁剪(附代码) | Python工具</a>
                        <span class="text-muted">剑客阿良_ALiang</span>

                        <div>前言本文提供将图片按照自定义尺寸进行裁剪的工具方法,一如既往的实用主义。环境依赖ffmpeg环境安装,可以参考我的另一篇文章:windowsffmpeg安装部署_阿良的博客-CSDN博客本文主要使用到的不是ffmpeg,而是ffprobe也在上面这篇文章中的zip包中。ffmpy安装:pipinstallffmpy-ihttps://pypi.douban.com/simple代码不废话了,上代码</div>
                    </li>
                    <li><a href="/article/1835491353451130880.htm"
                           title="【华为OD技术面试真题 - 技术面】- python八股文真题题库(4)" target="_blank">【华为OD技术面试真题 - 技术面】- python八股文真题题库(4)</a>
                        <span class="text-muted">算法大师</span>
<a class="tag" taget="_blank" href="/search/%E5%8D%8E%E4%B8%BAod/1.htm">华为od</a><a class="tag" taget="_blank" href="/search/%E9%9D%A2%E8%AF%95/1.htm">面试</a><a class="tag" taget="_blank" href="/search/python/1.htm">python</a>
                        <div>华为OD面试真题精选专栏:华为OD面试真题精选目录:2024华为OD面试手撕代码真题目录以及八股文真题目录文章目录华为OD面试真题精选**1.Python中的`with`**用途和功能自动资源管理示例:文件操作上下文管理协议示例代码工作流程解析优点2.\_\_new\_\_和**\_\_init\_\_**区别__new____init__区别总结3.**切片(Slicing)操作**基本切片语法</div>
                    </li>
                                <li><a href="/article/117.htm"
                                       title="Algorithm" target="_blank">Algorithm</a>
                                    <span class="text-muted">香水浓</span>
<a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/Algorithm/1.htm">Algorithm</a>
                                    <div>冒泡排序 
 

	public static void sort(Integer[] param) {
		for (int i = param.length - 1; i > 0; i--) {
			for (int j = 0; j < i; j++) {
				int current = param[j];
				int next = param[j + 1];</div>
                                </li>
                                <li><a href="/article/244.htm"
                                       title="mongoDB 复杂查询表达式" target="_blank">mongoDB 复杂查询表达式</a>
                                    <span class="text-muted">开窍的石头</span>
<a class="tag" taget="_blank" href="/search/mongodb/1.htm">mongodb</a>
                                    <div>1:count 
   Pg: db.user.find().count(); 
   统计多少条数据 
2:不等于$ne 
   Pg: db.user.find({_id:{$ne:3}},{name:1,sex:1,_id:0}); 
   查询id不等于3的数据。 
3:大于$gt $gte(大于等于) 
&n</div>
                                </li>
                                <li><a href="/article/371.htm"
                                       title="Jboss Java heap space异常解决方法, jboss OutOfMemoryError : PermGen space" target="_blank">Jboss Java heap space异常解决方法, jboss OutOfMemoryError : PermGen space</a>
                                    <span class="text-muted">0624chenhong</span>
<a class="tag" taget="_blank" href="/search/jvm/1.htm">jvm</a><a class="tag" taget="_blank" href="/search/jboss/1.htm">jboss</a>
                                    <div>转自 
http://blog.csdn.net/zou274/article/details/5552630 
 
解决办法: 
 
window->preferences->java->installed jres->edit jre 
把default vm arguments 的参数设为-Xms64m -Xmx512m 
 
 
 
----------------</div>
                                </li>
                                <li><a href="/article/498.htm"
                                       title="文件上传 下载 解析 相对路径" target="_blank">文件上传 下载 解析 相对路径</a>
                                    <span class="text-muted">不懂事的小屁孩</span>
<a class="tag" taget="_blank" href="/search/%E6%96%87%E4%BB%B6%E4%B8%8A%E4%BC%A0/1.htm">文件上传</a>
                                    <div>有点坑吧,弄这么一个简单的东西弄了一天多,身边还有大神指导着,网上各种百度着。 
下面总结一下遇到的问题: 
 
文件上传,在页面上传的时候,不要想着去操作绝对路径,浏览器会对客户端的信息进行保护,避免用户信息收到攻击。 
在上传图片,或者文件时,使用form表单来操作。 
前台通过form表单传输一个流到后台,而不是ajax传递参数到后台,代码如下: 
 

<form action=&</div>
                                </li>
                                <li><a href="/article/625.htm"
                                       title="怎么实现qq空间批量点赞" target="_blank">怎么实现qq空间批量点赞</a>
                                    <span class="text-muted">换个号韩国红果果</span>
<a class="tag" taget="_blank" href="/search/qq/1.htm">qq</a>
                                    <div>纯粹为了好玩!! 
逻辑很简单 
1 打开浏览器console;输入以下代码。 
先上添加赞的代码 
 

var tools={};
		//添加所有赞
		function  init(){
			document.body.scrollTop=10000;
				setTimeout(function(){document.body.scrollTop=0;},2000);//加</div>
                                </li>
                                <li><a href="/article/752.htm"
                                       title="判断是否为中文" target="_blank">判断是否为中文</a>
                                    <span class="text-muted">灵静志远</span>
<a class="tag" taget="_blank" href="/search/%E4%B8%AD%E6%96%87/1.htm">中文</a>
                                    <div>方法一: 
public class Zhidao { 
 public static void main(String args[]) { 
 String s = "sdf灭礌 kjl d{';\fdsjlk是"; 
 int n=0; 
 for(int i=0; i<s.length(); i++) { 
 n = (int)s.charAt(i); 
 if((</div>
                                </li>
                                <li><a href="/article/879.htm"
                                       title="一个电话面试后总结" target="_blank">一个电话面试后总结</a>
                                    <span class="text-muted">a-john</span>
<a class="tag" taget="_blank" href="/search/%E9%9D%A2%E8%AF%95/1.htm">面试</a>
                                    <div>今天,接了一个电话面试,对于还是初学者的我来说,紧张了半天。 
面试的问题分了层次,对于一类问题,由简到难。自己觉得回答不好的地方作了一下总结: 
  
在谈到集合类的时候,举几个常用的集合类,想都没想,直接说了list,map。 
  
然后对list和map分别举几个类型: 
  
list方面:ArrayList,LinkedList。在谈到他们的区别时,愣住了</div>
                                </li>
                                <li><a href="/article/1006.htm"
                                       title="MSSQL中Escape转义的使用" target="_blank">MSSQL中Escape转义的使用</a>
                                    <span class="text-muted">aijuans</span>
<a class="tag" taget="_blank" href="/search/MSSQL/1.htm">MSSQL</a>
                                    <div>IF OBJECT_ID('tempdb..#ABC') is not null
drop table tempdb..#ABC


create table #ABC
(
PATHNAME NVARCHAR(50)
)


insert into #ABC
SELECT N'/ABCDEFGHI' 
UNION ALL SELECT N'/ABCDGAFGASASSDFA' 
UNION ALL</div>
                                </li>
                                <li><a href="/article/1133.htm"
                                       title="一个简单的存储过程" target="_blank">一个简单的存储过程</a>
                                    <span class="text-muted">asialee</span>
<a class="tag" taget="_blank" href="/search/mysql/1.htm">mysql</a><a class="tag" taget="_blank" href="/search/%E5%AD%98%E5%82%A8%E8%BF%87%E7%A8%8B/1.htm">存储过程</a><a class="tag" taget="_blank" href="/search/%E6%9E%84%E9%80%A0%E6%95%B0%E6%8D%AE/1.htm">构造数据</a><a class="tag" taget="_blank" href="/search/%E6%89%B9%E9%87%8F%E6%8F%92%E5%85%A5/1.htm">批量插入</a>
                                    <div>           今天要批量的生成一批测试数据,其中中间有部分数据是变化的,本来想写个程序来生成的,后来想到存储过程就可以搞定,所以随手写了一个,记录在此: 
  
         
DELIMITER $$  
DROP PROCEDURE IF EXISTS inse</div>
                                </li>
                                <li><a href="/article/1260.htm"
                                       title="annot convert from HomeFragment_1 to Fragment" target="_blank">annot convert from HomeFragment_1 to Fragment</a>
                                    <span class="text-muted">百合不是茶</span>
<a class="tag" taget="_blank" href="/search/android/1.htm">android</a><a class="tag" taget="_blank" href="/search/%E5%AF%BC%E5%8C%85%E9%94%99%E8%AF%AF/1.htm">导包错误</a>
                                    <div>创建了几个类继承Fragment, 需要将创建的类存储在ArrayList<Fragment>中; 出现不能将new 出来的对象放到队列中,原因很简单; 
    创建类时引入包是:import android.app.Fragment; 
  
   创建队列和对象时使用的包是:import android.support.v4.ap</div>
                                </li>
                                <li><a href="/article/1387.htm"
                                       title="Weblogic10两种修改端口的方法" target="_blank">Weblogic10两种修改端口的方法</a>
                                    <span class="text-muted">bijian1013</span>
<a class="tag" taget="_blank" href="/search/weblogic/1.htm">weblogic</a><a class="tag" taget="_blank" href="/search/%E7%AB%AF%E5%8F%A3%E5%8F%B7/1.htm">端口号</a><a class="tag" taget="_blank" href="/search/%E9%85%8D%E7%BD%AE%E7%AE%A1%E7%90%86/1.htm">配置管理</a><a class="tag" taget="_blank" href="/search/config.xml/1.htm">config.xml</a>
                                    <div>一.进入控制台进行修改    1.进入控制台:  http://127.0.0.1:7001/console     2.展开左边树菜单         域结构->环境->服务器-->点击AdminServer(管理) &</div>
                                </li>
                                <li><a href="/article/1514.htm"
                                       title="mysql 操作指令" target="_blank">mysql 操作指令</a>
                                    <span class="text-muted">征客丶</span>
<a class="tag" taget="_blank" href="/search/mysql/1.htm">mysql</a>
                                    <div>一、连接mysql 
进入 mysql 的安装目录; 
$ bin/mysql -p [host IP 如果是登录本地的mysql 可以不写 -p 直接 -u] -u [userName] -p 
输入密码,回车,接连; 
 
二、权限操作[如果你很了解mysql数据库后,你可以直接去修改系统表,然后用 mysql> flush privileges; 指令让权限生效] 
1、赋权 
mys</div>
                                </li>
                                <li><a href="/article/1641.htm"
                                       title="【Hive一】Hive入门" target="_blank">【Hive一】Hive入门</a>
                                    <span class="text-muted">bit1129</span>
<a class="tag" taget="_blank" href="/search/hive/1.htm">hive</a>
                                    <div>Hive安装与配置 
Hive的运行需要依赖于Hadoop,因此需要首先安装Hadoop2.5.2,并且Hive的启动前需要首先启动Hadoop。 
  Hive安装和配置的步骤 
  
1. 从如下地址下载Hive0.14.0 
  
http://mirror.bit.edu.cn/apache/hive/ 
  
 2.解压hive,在系统变</div>
                                </li>
                                <li><a href="/article/1768.htm"
                                       title="ajax 三种提交请求的方法" target="_blank">ajax 三种提交请求的方法</a>
                                    <span class="text-muted">BlueSkator</span>
<a class="tag" taget="_blank" href="/search/Ajax/1.htm">Ajax</a><a class="tag" taget="_blank" href="/search/jqery/1.htm">jqery</a>
                                    <div>1、ajax 提交请求 
$.ajax({
			type:"post",
			url : "${ctx}/front/Hotel/getAllHotelByAjax.do",
			dataType : "json",
			success : function(result) {
				try {
					for(v</div>
                                </li>
                                <li><a href="/article/1895.htm"
                                       title="mongodb开发环境下的搭建入门" target="_blank">mongodb开发环境下的搭建入门</a>
                                    <span class="text-muted">braveCS</span>
<a class="tag" taget="_blank" href="/search/%E8%BF%90%E7%BB%B4/1.htm">运维</a>
                                    <div>  
linux下安装mongodb 
1)官网下载mongodb-linux-x86_64-rhel62-3.0.4.gz 
2)linux 解压   
gzip -d mongodb-linux-x86_64-rhel62-3.0.4.gz; 
mv mongodb-linux-x86_64-rhel62-3.0.4 mongodb-linux-x86_64-rhel62-</div>
                                </li>
                                <li><a href="/article/2022.htm"
                                       title="编程之美-最短摘要的生成" target="_blank">编程之美-最短摘要的生成</a>
                                    <span class="text-muted">bylijinnan</span>
<a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84/1.htm">数据结构</a><a class="tag" taget="_blank" href="/search/%E7%AE%97%E6%B3%95/1.htm">算法</a><a class="tag" taget="_blank" href="/search/%E7%BC%96%E7%A8%8B%E4%B9%8B%E7%BE%8E/1.htm">编程之美</a>
                                    <div>

import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;

public class ShortestAbstract {

	/**
	 * 编程之美 最短摘要的生成
	 * 扫描过程始终保持一个[pBegin,pEnd]的range,初始化确保[pBegin,pEnd]的ran</div>
                                </li>
                                <li><a href="/article/2149.htm"
                                       title="json数据解析及typeof" target="_blank">json数据解析及typeof</a>
                                    <span class="text-muted">chengxuyuancsdn</span>
<a class="tag" taget="_blank" href="/search/js/1.htm">js</a><a class="tag" taget="_blank" href="/search/typeof/1.htm">typeof</a><a class="tag" taget="_blank" href="/search/json%E8%A7%A3%E6%9E%90/1.htm">json解析</a>
                                    <div>   
       // json格式
	var people='{"authors": [{"firstName": "AAA","lastName": "BBB"},'
		                    +' {"firstName": "CCC&</div>
                                </li>
                                <li><a href="/article/2276.htm"
                                       title="流程系统设计的层次和目标" target="_blank">流程系统设计的层次和目标</a>
                                    <span class="text-muted">comsci</span>
<a class="tag" taget="_blank" href="/search/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/1.htm">设计模式</a><a class="tag" taget="_blank" href="/search/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84/1.htm">数据结构</a><a class="tag" taget="_blank" href="/search/sql/1.htm">sql</a><a class="tag" taget="_blank" href="/search/%E6%A1%86%E6%9E%B6/1.htm">框架</a><a class="tag" taget="_blank" href="/search/%E8%84%9A%E6%9C%AC/1.htm">脚本</a>
                                    <div> 
                              流程系统设计的层次和目标 
 
 
 </div>
                                </li>
                                <li><a href="/article/2403.htm"
                                       title="RMAN List和report 命令" target="_blank">RMAN List和report 命令</a>
                                    <span class="text-muted">daizj</span>
<a class="tag" taget="_blank" href="/search/oracle/1.htm">oracle</a><a class="tag" taget="_blank" href="/search/list/1.htm">list</a><a class="tag" taget="_blank" href="/search/report/1.htm">report</a><a class="tag" taget="_blank" href="/search/rman/1.htm">rman</a>
                                    <div>LIST 命令 
使用RMAN LIST 命令显示有关资料档案库中记录的备份集、代理副本和映像副本的 
信息。使用此命令可列出: 
• RMAN 资料档案库中状态不是AVAILABLE 的备份和副本 
• 可用的且可以用于还原操作的数据文件备份和副本 
• 备份集和副本,其中包含指定数据文件列表或指定表空间的备份 
• 包含指定名称或范围的所有归档日志备份的备份集和副本 
• 由标记、完成时间、可</div>
                                </li>
                                <li><a href="/article/2530.htm"
                                       title="二叉树:红黑树" target="_blank">二叉树:红黑树</a>
                                    <span class="text-muted">dieslrae</span>
<a class="tag" taget="_blank" href="/search/%E4%BA%8C%E5%8F%89%E6%A0%91/1.htm">二叉树</a>
                                    <div>    红黑树是一种自平衡的二叉树,它的查找,插入,删除操作时间复杂度皆为O(logN),不会出现普通二叉搜索树在最差情况时时间复杂度会变为O(N)的问题. 
    红黑树必须遵循红黑规则,规则如下 
    
1、每个节点不是红就是黑。     2、根总是黑的  &</div>
                                </li>
                                <li><a href="/article/2657.htm"
                                       title="C语言homework3,7个小题目的代码" target="_blank">C语言homework3,7个小题目的代码</a>
                                    <span class="text-muted">dcj3sjt126com</span>
<a class="tag" taget="_blank" href="/search/c/1.htm">c</a>
                                    <div>1、打印100以内的所有奇数。 
# include <stdio.h>

int main(void)
{
	int i;

	for (i=1; i<=100; i++)
	{
		if (i%2 != 0)
			printf("%d ", i);
	}

	return 0;
}
 
 2、从键盘上输入10个整数,</div>
                                </li>
                                <li><a href="/article/2784.htm"
                                       title="自定义按钮, 图片在上, 文字在下, 居中显示" target="_blank">自定义按钮, 图片在上, 文字在下, 居中显示</a>
                                    <span class="text-muted">dcj3sjt126com</span>
<a class="tag" taget="_blank" href="/search/%E8%87%AA%E5%AE%9A%E4%B9%89/1.htm">自定义</a>
                                    <div>#import <UIKit/UIKit.h>

@interface MyButton : UIButton

-(void)setFrame:(CGRect)frame ImageName:(NSString*)imageName Target:(id)target Action:(SEL)action Title:(NSString*)title Font:(CGFloa</div>
                                </li>
                                <li><a href="/article/2911.htm"
                                       title="MySQL查询语句练习题,测试足够用了" target="_blank">MySQL查询语句练习题,测试足够用了</a>
                                    <span class="text-muted">flyvszhb</span>
<a class="tag" taget="_blank" href="/search/sql/1.htm">sql</a><a class="tag" taget="_blank" href="/search/mysql/1.htm">mysql</a>
                                    <div>http://blog.sina.com.cn/s/blog_767d65530101861c.html 
1.创建student和score表 
CREATE  TABLE  student ( 
id  INT(10)  NOT NULL  UNIQUE  PRIMARY KEY  , 
name  VARCHAR</div>
                                </li>
                                <li><a href="/article/3038.htm"
                                       title="转:MyBatis Generator 详解" target="_blank">转:MyBatis Generator 详解</a>
                                    <span class="text-muted">happyqing</span>
<a class="tag" taget="_blank" href="/search/mybatis/1.htm">mybatis</a>
                                    <div>  
MyBatis Generator 详解 
http://blog.csdn.net/isea533/article/details/42102297 
  
MyBatis Generator详解 
http://git.oschina.net/free/Mybatis_Utils/blob/master/MybatisGeneator/MybatisGeneator.</div>
                                </li>
                                <li><a href="/article/3165.htm"
                                       title="让程序员少走弯路的14个忠告" target="_blank">让程序员少走弯路的14个忠告</a>
                                    <span class="text-muted">jingjing0907</span>
<a class="tag" taget="_blank" href="/search/%E5%B7%A5%E4%BD%9C/1.htm">工作</a><a class="tag" taget="_blank" href="/search/%E8%AE%A1%E5%88%92/1.htm">计划</a><a class="tag" taget="_blank" href="/search/%E5%AD%A6%E4%B9%A0/1.htm">学习</a>
                                    <div>  
无论是谁,在刚进入某个领域之时,有再大的雄心壮志也敌不过眼前的迷茫:不知道应该怎么做,不知道应该做什么。下面是一名软件开发人员所学到的经验,希望能对大家有所帮助 
  
1.不要害怕在工作中学习。  
只要有电脑,就可以通过电子阅读器阅读报纸和大多数书籍。如果你只是做好自己的本职工作以及分配的任务,那是学不到很多东西的。如果你盲目地要求更多的工作,也是不可能提升自己的。放</div>
                                </li>
                                <li><a href="/article/3292.htm"
                                       title="nginx和NetScaler区别" target="_blank">nginx和NetScaler区别</a>
                                    <span class="text-muted">流浪鱼</span>
<a class="tag" taget="_blank" href="/search/nginx/1.htm">nginx</a>
                                    <div>NetScaler是一个完整的包含操作系统和应用交付功能的产品,Nginx并不包含操作系统,在处理连接方面,需要依赖于操作系统,所以在并发连接数方面和防DoS攻击方面,Nginx不具备优势。 
2.易用性方面差别也比较大。Nginx对管理员的水平要求比较高,参数比较多,不确定性给运营带来隐患。在NetScaler常见的配置如健康检查,HA等,在Nginx上的配置的实现相对复杂。 
3.策略灵活度方</div>
                                </li>
                                <li><a href="/article/3419.htm"
                                       title="第11章 动画效果(下)" target="_blank">第11章 动画效果(下)</a>
                                    <span class="text-muted">onestopweb</span>
<a class="tag" taget="_blank" href="/search/%E5%8A%A8%E7%94%BB/1.htm">动画</a>
                                    <div>index.html 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/</div>
                                </li>
                                <li><a href="/article/3546.htm"
                                       title="FAQ - SAP BW BO roadmap" target="_blank">FAQ - SAP BW BO roadmap</a>
                                    <span class="text-muted">blueoxygen</span>
<a class="tag" taget="_blank" href="/search/BO/1.htm">BO</a><a class="tag" taget="_blank" href="/search/BW/1.htm">BW</a>
                                    <div>http://www.sdn.sap.com/irj/boc/business-objects-for-sap-faq 
  
Besides, I care that how to integrate tightly. 
  
By the way, for BW consultants, please just focus on Query Designer which i</div>
                                </li>
                                <li><a href="/article/3673.htm"
                                       title="关于java堆内存溢出的几种情况" target="_blank">关于java堆内存溢出的几种情况</a>
                                    <span class="text-muted">tomcat_oracle</span>
<a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/jvm/1.htm">jvm</a><a class="tag" taget="_blank" href="/search/jdk/1.htm">jdk</a><a class="tag" taget="_blank" href="/search/thread/1.htm">thread</a>
                                    <div>【情况一】:      
java.lang.OutOfMemoryError: Java heap space:这种是java堆内存不够,一个原因是真不够,另一个原因是程序中有死循环;     如果是java堆内存不够的话,可以通过调整JVM下面的配置来解决:     <jvm-arg>-Xms3062m</jvm-arg>     <jvm-arg>-Xmx</div>
                                </li>
                                <li><a href="/article/3800.htm"
                                       title="Manifest.permission_group权限组" target="_blank">Manifest.permission_group权限组</a>
                                    <span class="text-muted">阿尔萨斯</span>
<a class="tag" taget="_blank" href="/search/Permission/1.htm">Permission</a>
                                    <div>结构 
继承关系 
public static final class Manifest.permission_group extends Object 
java.lang.Object 
android. Manifest.permission_group 常量 
ACCOUNTS 直接通过统计管理器访问管理的统计 
COST_MONEY可以用来让用户花钱但不需要通过与他们直接牵涉的权限 
D</div>
                                </li>
                </ul>
            </div>
        </div>
    </div>

<div>
    <div class="container">
        <div class="indexes">
            <strong>按字母分类:</strong>
            <a href="/tags/A/1.htm" target="_blank">A</a><a href="/tags/B/1.htm" target="_blank">B</a><a href="/tags/C/1.htm" target="_blank">C</a><a
                href="/tags/D/1.htm" target="_blank">D</a><a href="/tags/E/1.htm" target="_blank">E</a><a href="/tags/F/1.htm" target="_blank">F</a><a
                href="/tags/G/1.htm" target="_blank">G</a><a href="/tags/H/1.htm" target="_blank">H</a><a href="/tags/I/1.htm" target="_blank">I</a><a
                href="/tags/J/1.htm" target="_blank">J</a><a href="/tags/K/1.htm" target="_blank">K</a><a href="/tags/L/1.htm" target="_blank">L</a><a
                href="/tags/M/1.htm" target="_blank">M</a><a href="/tags/N/1.htm" target="_blank">N</a><a href="/tags/O/1.htm" target="_blank">O</a><a
                href="/tags/P/1.htm" target="_blank">P</a><a href="/tags/Q/1.htm" target="_blank">Q</a><a href="/tags/R/1.htm" target="_blank">R</a><a
                href="/tags/S/1.htm" target="_blank">S</a><a href="/tags/T/1.htm" target="_blank">T</a><a href="/tags/U/1.htm" target="_blank">U</a><a
                href="/tags/V/1.htm" target="_blank">V</a><a href="/tags/W/1.htm" target="_blank">W</a><a href="/tags/X/1.htm" target="_blank">X</a><a
                href="/tags/Y/1.htm" target="_blank">Y</a><a href="/tags/Z/1.htm" target="_blank">Z</a><a href="/tags/0/1.htm" target="_blank">其他</a>
        </div>
    </div>
</div>
<footer id="footer" class="mb30 mt30">
    <div class="container">
        <div class="footBglm">
            <a target="_blank" href="/">首页</a> -
            <a target="_blank" href="/custom/about.htm">关于我们</a> -
            <a target="_blank" href="/search/Java/1.htm">站内搜索</a> -
            <a target="_blank" href="/sitemap.txt">Sitemap</a> -
            <a target="_blank" href="/custom/delete.htm">侵权投诉</a>
        </div>
        <div class="copyright">版权所有 IT知识库 CopyRight © 2000-2050 E-COM-NET.COM , All Rights Reserved.
<!--            <a href="https://beian.miit.gov.cn/" rel="nofollow" target="_blank">京ICP备09083238号</a><br>-->
        </div>
    </div>
</footer>
<!-- 代码高亮 -->
<script type="text/javascript" src="/static/syntaxhighlighter/scripts/shCore.js"></script>
<script type="text/javascript" src="/static/syntaxhighlighter/scripts/shLegacy.js"></script>
<script type="text/javascript" src="/static/syntaxhighlighter/scripts/shAutoloader.js"></script>
<link type="text/css" rel="stylesheet" href="/static/syntaxhighlighter/styles/shCoreDefault.css"/>
<script type="text/javascript" src="/static/syntaxhighlighter/src/my_start_1.js"></script>





</body>

</html>