写在前面
我相信很多小伙伴学完Python基础后,一定会去接触爬虫,也有很多人入门Python都是从爬虫开始的,包括我自己也是这样的。几乎所有学Python都知道requests这个库,它是大名鼎鼎K神的得意之作,非常非常非常好用
但是随时Python异步async的大流行,由于requests本身是阻塞的导致在使用异步的时候有些捉襟见肘。今天我就给大家推荐一个牛*的库,可以同时支持同步和异步的请求,一箭双雕,一起来看一下吧
如何安装
直接 pip install httpx 即可,非常方便
如果你觉得安装速度太慢的话,不妨试试这个:pip install httpx -i http://pypi.douban.com/simple --trusted-host pypi.douban.com
快速使用
同步的http请求
import httpx
response = httpx.get('http://www.example.org/')
print(response)
#output: <Response [200 OK]>
print(response.status_code)
#output:200
print(response.headers['content-type'])
#output:'text/html; charset=UTF-8'
print(reponse.text)
#output:网站源码
get()方法很简单,与requests库非常相似
异步请求
不了解Python异步函数的可以先去看看我这篇文章Python高级编程之异步函数 asyncawait的使用
异步的请求:
import httpx
import asyncio
async def main():
async with httpx.AsyncClient() as client:
#异步请求用 AsyncClient()
response = await client.get('http://www.example.org/')
print(response)
asyncio.run(main())
直接和Python内置的asyncio库进行组合使用,进行异步请求
强大的功能
httpx支持很多http的请求方式,除了我们常见的get请求之外 ,还支持自定义header,自定义post表单数据,发送文件分段上传,发送二进制请求数据等等。下面给大家简单演示一下:
import httpx
#在url中传递参数,我们在爬虫中经常用到
params = {'key1':'value1','key2':'value2'}
response = httpx.get('https://httpbin.org/get',params=params)
#发生post数据
httpx.post('https://httpbin.org/post',data={'key':'value'})
#自定义 Headers
url = 'https://httpbin.org/headers'
headers = {'user-agent':'my-app-test/4.1.2'}
response = httpx.get(url=url,headers=headers)
实战异步玩一下
既然httpx它的一个很大的卖点是异步,说了这么多,我们用一个小的异步爬虫案例来玩一下httpx库,并发爬取有道词典看看效果
from pyquery import PyQuery as pq
import asyncio
import httpx
import time
async def my_request(client,word='china'):
desc_text = ''
url_base = f'http://dict.youdao.com/w/eng/{word}/'
r = await client.get(url_base)
doc = pq(r.text)
for li in doc.items('#phrsListTab .trans-container ul li'):
desc_text += li.text()
print(desc_text)
async def main():
async with httpx.AsyncClient() as client: #异步请求用 AsyncClient()
start = time.time()
task_list = []
for i in range(100):
req = my_request(client)
task = asyncio.create_task(req)
task_list.append(task)
await asyncio.gather(*task_list)
end = time.time()
print(f'一共用时:{end-start}')
if __name__ == '__main__':
asyncio.run(main())
整个程序非常短30来行,非常简单,就分两部分:
- 第一部分:就是用httpx构造一个client发起异步请求,连续请求100次,然后把这个100个请求任务包裹在async框架里面,进行并发处理
- 第二部分:就是每一个去有道发起一个请求,然后用pyquery进行解析html文本数据
如果用requests库同步处理的花至少要52秒左右,可以看到httpx快得不止一点点
import time
import requests
from pyquery import PyQuery as pq
def my_request(word='china'):
desc_text = ''
url_base = f'http://dict.youdao.com/w/eng/{word}/'
r = requests.get(url_base)
doc = pq(r.text)
for li in doc.items('#phrsListTab .trans-container ul li'):
desc_text += li.text()
print(desc_text)
def main():
s = time.time()
for i in range(100):
my_request()
e = time.time()
print(f"一共用时:{e-s}")
if __name__ == '__main__':
main()
写在最后
上面只介绍了一部分功能,httpx还有很多强大的功能,使用方法跟requests差不多。requests能支持的httpx都支持,requests不能干的事情httpx也能干。这个库野心还是很大的,当你的项目既要支持同步请求和也要支持异步请求的时候,httpx就该上场啦!有兴趣的小伙伴赶紧试试吧