Python 环境加载中…

一次请求发生了什么

3 道练习题·预计 50 分钟·做对一题解锁下一段

完整通读本章 →

教学 01 / 09· 已读

前言

上一章,咱们用三行代码就取回了一个网页。requests.get() 用起来很简单,可它背后到底发生了什么,咱们还没有细看。

有的童鞋可能会想:能取回来不就行了,为什么还要弄清楚这些?因为写爬虫的时候,问题多半就出在这里。比如网址拼错了一个字符,状态码不是 200 却没发现,拿回来的不是网页而是一段数据,或者中文变成了乱码……

不知道各位童鞋有没有这种体会:程序一跑不通,就只会盯着自己的代码看。其实很多时候,答案就写在网站发回来的响应里,只要你知道去哪儿找。

所以这一章,咱们把一次请求从头到尾拆开来看:网址由哪几部分组成,程序发出去的是什么,网站发回来的又有些什么。

学这一章之前,需要先学完 爬虫课第 1 章 ,会用 requests.get() 取回网页、看状态码。

目录

这一章会学到:

  • 一、网址由哪几部分组成——用 urlparse() 把网址拆开
  • 二、请求和响应——程序发出去什么,网站发回来什么
  • 三、状态码——200、404 之外,还有哪些
  • 四、拿回来的不一定是网页——JSON 数据和 response.json()
  • 五、查询参数——params 帮你拼网址
  • 六、常见坑
  • 七、自己查一次文档——每个状态码叫什么名字
  • 八、小结与回看

学完这一章,你能看懂一次请求的来龙去脉,取回网页以后知道先检查什么、去哪儿找问题。

教学 02 / 09

一、网址由哪几部分组成

拆开一次请求,先从最熟悉的网址说起。下面是一个完整的网址:

文本
https://learn-py.org/lab/bookstore/page/2/?sort=price#top

别看它是一整串,其实是由好几段拼起来的。怎么看出是哪几段呢?Python 自带的 urllib.parse 模块,就能把它拆开:

Python· 可在网页运行
from urllib.parse import urlparse

parts = urlparse('https://learn-py.org/lab/bookstore/page/2/?sort=price#top')
print(parts.scheme)
print(parts.netloc)
print(parts.path)
print(parts.query)
print(parts.fragment)

输出的结果:

文本
https
learn-py.org
/lab/bookstore/page/2/
sort=price
top

拆出来一共五段。每一段是什么,对照下面这张表,一段一段地看:

部分例子是什么
schemehttps协议,也就是怎么跟网站说话。https 是加密过的,比 http 安全
netloclearn-py.org域名,网站在哪儿
path/lab/bookstore/page/2/路径,要网站上的哪个网页
querysort=price查询参数,? 后面的部分,给网站附带的要求,比如按价格排序
fragmenttop锚点,# 后面的部分,只在浏览器里用来跳到页面的某个位置,不会发给网站

这五段里,写爬虫时最常打交道的,是路径和查询参数。

先说路径。两点书店的列表页,就是靠路径来分页的:第 2 页是 /lab/bookstore/page/2/ ,第 3 页是 /lab/bookstore/page/3/ 。看出了这个规律,就能用循环把每一页的网址拼出来。上一章连着取好几页,用的就是这个办法。

再说查询参数。上面的例子里只有一个参数,其实查询参数可以有好几个,用 & 连起来。要把它们一个一个分开,可以用同一个模块里的 parse_qs() ,它能把查询参数拆成字典:

Python· 可在网页运行
from urllib.parse import parse_qs

print(parse_qs('page=2&sort=price&tag=编程'))

输出的结果:

文本
{'page': ['2'], 'sort': ['price'], 'tag': ['编程']}

细心的童鞋会发现,每个值都装在了一个列表里,连只有一个值的 page 也是这样。为什么要这样呢?因为同一个参数可以出现好几次,比如 tag=编程&tag=小说 ,这时候一个值就装不下了。

下面先做一道练习,用 urlparse() 和 parse_qs() 自己拆一个网址。

练习 1 / 3把网址拆开题目有问题?

用 urlparse() 拆开下面这个网址,依次打印域名、路径,再用 parse_qs() 取出查询参数 sort 和 order 的值,打印在同一行:

文本
https://learn-py.org/lab/bookstore/page/3/?sort=price&order=desc#list

运行后的输出应该是:

文本
learn-py.org
/lab/bookstore/page/3/
price desc
main.py
可编辑
做对当前题解锁下一段 ·03

推荐一个,全网最全最友好的中文 AI 编程指南: coding.stormzhang.ai

学习目录