使用HTTP客户端在Python中进行网页抓取
在网页抓取的上下中,HTTP客户端向目标网站发送请求,并检索网站的HTML代码或JSON有效负载等信息。
HTTP客户端并不直接指向代码开发者,而是指在客户端-服务器模型中发送HTTP请求的部分。这个客户端是一个软件程序,例如网页浏览器(如Chrome、Firefox等)或者其他可以发送HTTP请求的程序(这样的程序可以用各种编程语言编写,包括Python)。
当我们编写爬虫程序时,我们编写的代码实际上创建的就是一个这样的HTTP客户端。
Python HTTP库
Python中有许多用来创建HTTP客户端和处理HTTP请求的库,被称为Python HTTP库。
Requests
被称为python中最受欢迎的HTTP库。
功能强大且用户友好,提供了许多便捷的方法用于发送各种HTTP请求。但缺乏对异步执行的支持,对于这种情况,可以使用HTTPX库。
Python Requests 库的主要特点:
- 保持活动状态和连接池
- 浏览器式SSL验证
- HTTP(S)代理支持
- 连接超时
- 分块请求
安装请求
pip install requests
代码示例
向目标网站发送请求,检索器HTML代码,并将结果打印到控制台。
import requests
response = requests.get('https://news.ycombinator.com')
print(response.text)
-
import requests
这行代码导入了Python的
requests
库。这是Python中最常用的HTTP客户端库,用于发送各种类型的HTTP请求。 -
response = requests.get('https://news.ycombinator.com')
这行代码发送一个HTTP GET请求到URL “https://news.ycombinator.com”。GET是一种HTTP方法,我们用它来请求服务器发送一些特定资源。在这个案例中,这个资源就是"https://news.ycombinator.com"首页的HTML内容。
requests.get()
函数返回一个Response
对象,代表了服务器的响应数据。这个Response
对象有许多属性和方法可以让我们访问响应的详细信息,比如状态码、头部、内容等。 -
print(response.text)
这行代码打印了响应对象的文本内容。
Response.text
属性包含了服务器返回的内容,这通常是一个字符串(对于HTML或JSON响应)。在这个案例中,它是"https://news.ycombinator.com"首页的HTML代码
HTTPX
HTTPX是个功能齐全的Python HTTP客户端库,包括集成的命令行客户端,同时提供同步和异步API。
HTTPX的主要特点
- 广泛请求兼容的API
- 继承的命令行客户端
- 标准同步接口,但如果需要,还可以支持异步
- 完整类型注释
安装HTTPX
pip install httpx
代码示例
与 Requests
示例类似,我们将向目标网站发送请求,检索页面的 HTML 并将其与请求状态代码一起打印到控制台。
HTTPX同步代码示例
import httpx
response = httpx.get('https://news.ycombinator.com')
status_code = response.status_code
html = response.text
print(status_code)
print(html[:200]) # print first 200 characters of html
import httpx
: 这行代码是Python语言中的模块导入语句,它导入了httpx
库,这是一个强大的HTTP客户端库,支持静态(同步)和异步HTTP请求,并且自动处理连接和线程池,因此可以更方便地发送请求和处理响应。response = httpx.get('https://news.ycombinator.com')
: 这行代码通过httpx库的get
方法向"https://news.ycombinator.com"发送了一个HTTP GET请求,并将响应存储在了变量response
中。HTTP GET请求是HTTP协议的一个方法,它用于请求服务器上指定资源的数据(在这种情况下,资源是网站的HTML内容)。status_code = response.status_code
: 这行代码获取了HTTP响应的状态码并将其存储在变量status_code
中。HTTP状态码是服务器在响应中返回的一个三位数字,它表示了请求的处理情况,比如200表示请求成功,404表示请求的资源找不到。html = response.text
: 这行代码从响应中提取了HTML文本并将其存储在变量html
中。可以通过response.text
获取响应的文本。print(status_code)
: 这行代码在控制台上输出状态码。print(html[:200])
: 这行代码在控制台上输出HTML内容的前200个字符。在Python字符串中,使用[a:b]
可以截取字符串的一部分,此处是从头截取到第200个字符。
利用 AsyncIO 的 HTTPX 异步代码示例
import asyncio
import httpx
async def main() -> None:
async with httpx.AsyncClient() as client:
response = await client.get('https://news.ycombinator.com')
status_code = response.status_code
html = response.text
print(status_code)
print(html[:200]) # print first 200 characters of html
if __name__ == '__main__':
asyncio.run(main())
import asyncio, httpx
:这行代码导入了Python的asyncio
和httpx
模块。asyncio
是Python的一个用于编写单线程并发代码的库,使用事件循环驱动的协程。httpx
是一个强大的,支持同步或异步的请求的HTTP库。async def main() -> None:
:异步定义函数main()
, 这是一个协程函数,用async def
来声明。差异是异步函数在调用时不会立即执行,而是返回一个协程对象。async with httpx.AsyncClient() as client:
:此行代码创建了httpx.AsyncClient()
的上下文管理器,该客户端支持与服务器建立持久连接,重用SSL会话,并在全局范围内提供HTTP / 2和连接池。response = await client.get('https://news.ycombinator.com')
:await
关键字用于等待协程的完成。在这里,我们在异步客户端上运行get
方法并等待响应。这样就不必等待服务器的响应,我们的程序可以在此期间执行其他任务。status_code = response.status_code
和html = response.text
:这两行代码跟上述代码解析相同,获取响应的状态码和消息print(response.status_code)
和print(html)
:同样跟上述解析相同,打印状态码和获取到的网页内容的前200个字符。if __name__ == '__main__':
和asyncio.run(main())
:如果Python文件以模块方式被别的文件调用时,其__name__
为模块名,而如果单独执行这个文件的话,__name__
的值就是'__main__'
。此处asyncio.run(main())
是异步I/O的一个关键步骤,他可以并发执行任务,提高整体代码的执行效率。
HTTPX的特性
- HTTP/1.1和HTTP/2的支持:HTTP/2可以更快地加载网页,因为它允许在一个连接上处理多个请求和响应。这并非异步编程,而是连接复用。
- 用于同步代码和异步代码的客户端接口:"httpx"有两种客户端:
httpx.Client
用于同步代码,httpx.AsyncClient
用于异步代码。 - 请求内容的直接序列化/反序列化:Requests库需要手动序列化或反序列化JSON内容,而"HTTPX"可以直接处理。
参考链接:https://blog.apify.com/web-scraping-python/#preparing-python-coding-environment-for-web-scraping